Compare commits
29 Commits
temp-cpp-g
...
eevee-gpen
Author | SHA1 | Date | |
---|---|---|---|
ad3d5b5ff6 | |||
2471986440 | |||
7672e32137 | |||
82cc3b5cc2 | |||
786aa4b518 | |||
0330805ec7 | |||
e4ed986b97 | |||
4350b18d85 | |||
37ad0a95cf | |||
c49681b43b | |||
35640a8d60 | |||
fcd2e920b4 | |||
f3d010df11 | |||
cf9a23d9a2 | |||
a0981ce0ff | |||
f97b9e99bc | |||
90516f1af4 | |||
76de19a1d4 | |||
1605a19bc4 | |||
64ab5f77a2 | |||
d94e3814c5 | |||
a98fd628ca | |||
52ec2269af | |||
65700fc064 | |||
3163e8988c | |||
8df9002ad4 | |||
b5cfd81519 | |||
88395ad654 | |||
1fd04e0dec |
@@ -133,7 +133,7 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel):
|
|||||||
else:
|
else:
|
||||||
self.draw_layers(context, layout, gpd)
|
self.draw_layers(context, layout, gpd)
|
||||||
|
|
||||||
def draw_layers(self, _context, layout, gpd):
|
def draw_layers(self, context, layout, gpd):
|
||||||
|
|
||||||
gpl = gpd.layers.active
|
gpl = gpd.layers.active
|
||||||
|
|
||||||
@@ -175,16 +175,18 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = True
|
layout.use_property_decorate = True
|
||||||
col = layout.column(align=True)
|
row = layout.row(align=True)
|
||||||
|
row.prop(gpl, "blend_mode", text="Blend")
|
||||||
|
|
||||||
col = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
col.prop(gpl, "blend_mode", text="Blend")
|
row.prop(gpl, "opacity", text="Opacity", slider=True)
|
||||||
|
|
||||||
col = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
col.prop(gpl, "opacity", text="Opacity", slider=True)
|
row.prop(gpl, "use_lights")
|
||||||
|
|
||||||
col = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
col.prop(gpl, "use_lights")
|
row.enabled = context.engine == 'BLENDER_EEVEE'
|
||||||
|
row.prop(gpl, "use_cast_shadows")
|
||||||
|
|
||||||
|
|
||||||
class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksPanel, Panel):
|
class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksPanel, Panel):
|
||||||
|
@@ -261,7 +261,14 @@ class MATERIAL_PT_gpencil_settings(GPMaterialButtonsPanel, Panel):
|
|||||||
|
|
||||||
ma = context.material
|
ma = context.material
|
||||||
gpcolor = ma.grease_pencil
|
gpcolor = ma.grease_pencil
|
||||||
layout.prop(gpcolor, "pass_index")
|
|
||||||
|
row = layout.row()
|
||||||
|
row.enabled = context.engine == 'BLENDER_EEVEE'
|
||||||
|
row.prop(gpcolor, "use_cast_shadows")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(gpcolor, "pass_index")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MATERIAL_PT_gpencil_material_presets(PresetPanel, Panel):
|
class MATERIAL_PT_gpencil_material_presets(PresetPanel, Panel):
|
||||||
|
@@ -731,6 +731,10 @@ class DOPESHEET_PT_gpencil_mode(LayersDopeSheetPanel, Panel):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(gpl, "use_lights")
|
row.prop(gpl, "use_lights")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.enabled = context.engine == 'BLENDER_EEVEE'
|
||||||
|
row.prop(gpl, "use_cast_shadows")
|
||||||
|
|
||||||
|
|
||||||
class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMasksPanel, Panel):
|
class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMasksPanel, Panel):
|
||||||
bl_label = "Masks"
|
bl_label = "Masks"
|
||||||
|
@@ -171,6 +171,10 @@ class TOPBAR_PT_gpencil_layers(Panel):
|
|||||||
srow = col.row(align=True)
|
srow = col.row(align=True)
|
||||||
srow.prop(gpl, "use_lights")
|
srow.prop(gpl, "use_lights")
|
||||||
|
|
||||||
|
srow = col.row(align=True)
|
||||||
|
srow.enabled = context.engine == 'BLENDER_EEVEE'
|
||||||
|
srow.prop(gpl, "use_cast_shadows")
|
||||||
|
|
||||||
col = row.column()
|
col = row.column()
|
||||||
|
|
||||||
sub = col.column(align=True)
|
sub = col.column(align=True)
|
||||||
|
@@ -295,7 +295,7 @@ void BKE_gpencil_material_attr_init(Material *ma)
|
|||||||
gp_style->texture_pixsize = 100.0f;
|
gp_style->texture_pixsize = 100.0f;
|
||||||
gp_style->mix_factor = 0.5f;
|
gp_style->mix_factor = 0.5f;
|
||||||
|
|
||||||
gp_style->flag |= GP_MATERIAL_STROKE_SHOW;
|
gp_style->flag |= GP_MATERIAL_STROKE_SHOW | GP_MATERIAL_CAST_SHADOWS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -131,6 +131,9 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
|
|||||||
else if (ob->type == OB_VOLUME) {
|
else if (ob->type == OB_VOLUME) {
|
||||||
EEVEE_volumes_cache_object_add(sldata, vedata, draw_ctx->scene, ob);
|
EEVEE_volumes_cache_object_add(sldata, vedata, draw_ctx->scene, ob);
|
||||||
}
|
}
|
||||||
|
else if (ob->type == OB_GPENCIL) {
|
||||||
|
EEVEE_gpencil_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||||
|
}
|
||||||
else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) {
|
else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) {
|
||||||
/* do not add any scene light sources to the cache */
|
/* do not add any scene light sources to the cache */
|
||||||
}
|
}
|
||||||
|
@@ -30,9 +30,11 @@
|
|||||||
#include "BLI_rand.h"
|
#include "BLI_rand.h"
|
||||||
#include "BLI_string_utils.h"
|
#include "BLI_string_utils.h"
|
||||||
|
|
||||||
|
#include "BKE_gpencil.h"
|
||||||
#include "BKE_paint.h"
|
#include "BKE_paint.h"
|
||||||
#include "BKE_particle.h"
|
#include "BKE_particle.h"
|
||||||
|
|
||||||
|
#include "DNA_gpencil_types.h"
|
||||||
#include "DNA_hair_types.h"
|
#include "DNA_hair_types.h"
|
||||||
#include "DNA_modifier_types.h"
|
#include "DNA_modifier_types.h"
|
||||||
#include "DNA_view3d_types.h"
|
#include "DNA_view3d_types.h"
|
||||||
@@ -42,6 +44,8 @@
|
|||||||
|
|
||||||
#include "DEG_depsgraph_query.h"
|
#include "DEG_depsgraph_query.h"
|
||||||
|
|
||||||
|
#include "ED_screen.h"
|
||||||
|
|
||||||
#include "eevee_engine.h"
|
#include "eevee_engine.h"
|
||||||
#include "eevee_lut.h"
|
#include "eevee_lut.h"
|
||||||
#include "eevee_private.h"
|
#include "eevee_private.h"
|
||||||
@@ -229,6 +233,14 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
|
|||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||||
EEVEE_PrivateData *g_data = stl->g_data;
|
EEVEE_PrivateData *g_data = stl->g_data;
|
||||||
|
|
||||||
|
g_data->cfra = (int)DEG_get_ctime(draw_ctx->depsgraph);
|
||||||
|
/* Grease pencil simplify. */
|
||||||
|
const bool playing = (draw_ctx->evil_C != NULL) ?
|
||||||
|
ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL :
|
||||||
|
false;
|
||||||
|
Scene *scene = draw_ctx->scene;
|
||||||
|
g_data->gpencil_simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, playing);
|
||||||
|
|
||||||
if (!e_data.util_tex) {
|
if (!e_data.util_tex) {
|
||||||
EEVEE_shaders_material_shaders_init();
|
EEVEE_shaders_material_shaders_init();
|
||||||
|
|
||||||
@@ -470,6 +482,7 @@ BLI_INLINE void material_shadow(EEVEE_Data *vedata,
|
|||||||
EEVEE_ViewLayerData *sldata,
|
EEVEE_ViewLayerData *sldata,
|
||||||
Material *ma,
|
Material *ma,
|
||||||
bool is_hair,
|
bool is_hair,
|
||||||
|
bool is_gpencil,
|
||||||
EeveeMaterialCache *emc)
|
EeveeMaterialCache *emc)
|
||||||
{
|
{
|
||||||
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
||||||
@@ -484,6 +497,7 @@ BLI_INLINE void material_shadow(EEVEE_Data *vedata,
|
|||||||
int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
|
int mat_options = VAR_MAT_MESH | VAR_MAT_DEPTH;
|
||||||
SET_FLAG_FROM_TEST(mat_options, use_shadow_shader, VAR_MAT_HASH);
|
SET_FLAG_FROM_TEST(mat_options, use_shadow_shader, VAR_MAT_HASH);
|
||||||
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
||||||
|
SET_FLAG_FROM_TEST(mat_options, is_gpencil, VAR_MAT_GPENCIL);
|
||||||
GPUMaterial *gpumat = (use_shadow_shader) ?
|
GPUMaterial *gpumat = (use_shadow_shader) ?
|
||||||
EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
|
EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
|
||||||
EEVEE_material_default_get(scene, ma, mat_options);
|
EEVEE_material_default_get(scene, ma, mat_options);
|
||||||
@@ -521,7 +535,8 @@ BLI_INLINE void material_shadow(EEVEE_Data *vedata,
|
|||||||
static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
||||||
EEVEE_ViewLayerData *sldata,
|
EEVEE_ViewLayerData *sldata,
|
||||||
Material *ma,
|
Material *ma,
|
||||||
const bool is_hair)
|
const bool is_hair,
|
||||||
|
const bool is_gpencil)
|
||||||
{
|
{
|
||||||
EEVEE_EffectsInfo *effects = vedata->stl->effects;
|
EEVEE_EffectsInfo *effects = vedata->stl->effects;
|
||||||
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
||||||
@@ -529,7 +544,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||||
Scene *scene = draw_ctx->scene;
|
Scene *scene = draw_ctx->scene;
|
||||||
|
|
||||||
const bool do_cull = !is_hair && (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
|
const bool do_cull = !is_gpencil && !is_hair && (ma->blend_flag & MA_BL_CULL_BACKFACE) != 0;
|
||||||
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
|
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
|
||||||
const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
|
const bool use_ssrefract = use_gpumat && ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) &&
|
||||||
((effects->enabled_effects & EFFECT_REFRACT) != 0);
|
((effects->enabled_effects & EFFECT_REFRACT) != 0);
|
||||||
@@ -537,7 +552,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
|
|
||||||
/* HACK: Assume the struct will never be smaller than our variations.
|
/* HACK: Assume the struct will never be smaller than our variations.
|
||||||
* This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
|
* This allow us to only keep one ghash and avoid bigger keys comparisons/hashing. */
|
||||||
void *key = (char *)ma + is_hair;
|
void *key = (char *)ma + is_hair + is_gpencil * 2;
|
||||||
/* Search for other material instances (sharing the same Material data-block). */
|
/* Search for other material instances (sharing the same Material data-block). */
|
||||||
EeveeMaterialCache **emc_p, *emc;
|
EeveeMaterialCache **emc_p, *emc;
|
||||||
if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
|
if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
|
||||||
@@ -546,7 +561,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
|
|
||||||
*emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
|
*emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
|
||||||
|
|
||||||
material_shadow(vedata, sldata, ma, is_hair, emc);
|
material_shadow(vedata, sldata, ma, is_hair, is_gpencil, emc);
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Depth Pass */
|
/* Depth Pass */
|
||||||
@@ -554,6 +569,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
|
SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
|
||||||
SET_FLAG_FROM_TEST(mat_options, use_depth_shader, VAR_MAT_HASH);
|
SET_FLAG_FROM_TEST(mat_options, use_depth_shader, VAR_MAT_HASH);
|
||||||
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
||||||
|
SET_FLAG_FROM_TEST(mat_options, is_gpencil, VAR_MAT_GPENCIL);
|
||||||
GPUMaterial *gpumat = (use_depth_shader) ?
|
GPUMaterial *gpumat = (use_depth_shader) ?
|
||||||
EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
|
EEVEE_material_get(vedata, scene, ma, NULL, mat_options) :
|
||||||
EEVEE_material_default_get(scene, ma, mat_options);
|
EEVEE_material_default_get(scene, ma, mat_options);
|
||||||
@@ -595,6 +611,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
int mat_options = VAR_MAT_MESH;
|
int mat_options = VAR_MAT_MESH;
|
||||||
SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
|
SET_FLAG_FROM_TEST(mat_options, use_ssrefract, VAR_MAT_REFRACT);
|
||||||
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
SET_FLAG_FROM_TEST(mat_options, is_hair, VAR_MAT_HAIR);
|
||||||
|
SET_FLAG_FROM_TEST(mat_options, is_gpencil, VAR_MAT_GPENCIL);
|
||||||
GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
|
GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
|
||||||
const bool use_sss = GPU_material_flag_get(gpumat, GPU_MATFLAG_SSS);
|
const bool use_sss = GPU_material_flag_get(gpumat, GPU_MATFLAG_SSS);
|
||||||
|
|
||||||
@@ -609,7 +626,7 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
|
|||||||
psl->material_cull_ps,
|
psl->material_cull_ps,
|
||||||
}[option];
|
}[option];
|
||||||
/* Hair are rendered inside the non-cull pass but needs to have a separate cache key */
|
/* Hair are rendered inside the non-cull pass but needs to have a separate cache key */
|
||||||
option = option * 2 + is_hair;
|
option = option * 3 + is_hair + is_gpencil * 2;
|
||||||
|
|
||||||
/* Search for the same shaders usage in the pass. */
|
/* Search for the same shaders usage in the pass. */
|
||||||
/* HACK: Assume the struct will never be smaller than our variations.
|
/* HACK: Assume the struct will never be smaller than our variations.
|
||||||
@@ -668,7 +685,7 @@ static EeveeMaterialCache material_transparent(EEVEE_Data *vedata,
|
|||||||
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_DEPTH_EQUAL |
|
||||||
DRW_STATE_BLEND_CUSTOM);
|
DRW_STATE_BLEND_CUSTOM);
|
||||||
|
|
||||||
material_shadow(vedata, sldata, ma, false, &emc);
|
material_shadow(vedata, sldata, ma, false, false, &emc);
|
||||||
|
|
||||||
if (use_prepass) {
|
if (use_prepass) {
|
||||||
/* Depth prepass */
|
/* Depth prepass */
|
||||||
@@ -735,15 +752,20 @@ BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot, bool holdou
|
|||||||
return ma;
|
return ma;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_INLINE EeveeMaterialCache eevee_material_cache_get(
|
BLI_INLINE EeveeMaterialCache eevee_material_cache_get(EEVEE_Data *vedata,
|
||||||
EEVEE_Data *vedata, EEVEE_ViewLayerData *sldata, Object *ob, int slot, bool is_hair)
|
EEVEE_ViewLayerData *sldata,
|
||||||
|
Object *ob,
|
||||||
|
int slot,
|
||||||
|
bool is_hair,
|
||||||
|
bool is_gpencil)
|
||||||
{
|
{
|
||||||
const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
|
const bool holdout = (ob->base_flag & BASE_HOLDOUT) != 0;
|
||||||
EeveeMaterialCache matcache;
|
EeveeMaterialCache matcache;
|
||||||
Material *ma = eevee_object_material_get(ob, slot, holdout);
|
Material *ma = eevee_object_material_get(ob, slot, holdout);
|
||||||
switch (ma->blend_method) {
|
switch (ma->blend_method) {
|
||||||
case MA_BM_BLEND:
|
case MA_BM_BLEND:
|
||||||
if (!is_hair) {
|
/* TODO(fclem) support gpencil transparent materials. */
|
||||||
|
if (!is_hair && !is_gpencil) {
|
||||||
matcache = material_transparent(vedata, sldata, ma);
|
matcache = material_transparent(vedata, sldata, ma);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -752,7 +774,7 @@ BLI_INLINE EeveeMaterialCache eevee_material_cache_get(
|
|||||||
case MA_BM_CLIP:
|
case MA_BM_CLIP:
|
||||||
case MA_BM_HASHED:
|
case MA_BM_HASHED:
|
||||||
default:
|
default:
|
||||||
matcache = material_opaque(vedata, sldata, ma, is_hair);
|
matcache = material_opaque(vedata, sldata, ma, is_hair, is_gpencil);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return matcache;
|
return matcache;
|
||||||
@@ -766,7 +788,8 @@ static void eevee_hair_cache_populate(EEVEE_Data *vedata,
|
|||||||
int matnr,
|
int matnr,
|
||||||
bool *cast_shadow)
|
bool *cast_shadow)
|
||||||
{
|
{
|
||||||
EeveeMaterialCache matcache = eevee_material_cache_get(vedata, sldata, ob, matnr - 1, true);
|
EeveeMaterialCache matcache = eevee_material_cache_get(
|
||||||
|
vedata, sldata, ob, matnr - 1, true, false);
|
||||||
|
|
||||||
if (matcache.depth_grp) {
|
if (matcache.depth_grp) {
|
||||||
*matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp);
|
*matcache.depth_grp_p = DRW_shgroup_hair_create_sub(ob, psys, md, matcache.depth_grp);
|
||||||
@@ -824,7 +847,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
|
|||||||
|
|
||||||
EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len);
|
EeveeMaterialCache *matcache = BLI_array_alloca(matcache, materials_len);
|
||||||
for (int i = 0; i < materials_len; i++) {
|
for (int i = 0; i < materials_len; i++) {
|
||||||
matcache[i] = eevee_material_cache_get(vedata, sldata, ob, i, false);
|
matcache[i] = eevee_material_cache_get(vedata, sldata, ob, i, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only support single volume material for now. */
|
/* Only support single volume material for now. */
|
||||||
@@ -930,6 +953,119 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
|
|||||||
eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, HAIR_MATERIAL_NR, cast_shadow);
|
eevee_hair_cache_populate(vedata, sldata, ob, NULL, NULL, HAIR_MATERIAL_NR, cast_shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct gpIterData {
|
||||||
|
EEVEE_PrivateData *pd;
|
||||||
|
Object *ob;
|
||||||
|
DRWShadingGroup *stroke_shadow_grp;
|
||||||
|
DRWShadingGroup *fill_shadow_grp;
|
||||||
|
int cfra;
|
||||||
|
float plane[4];
|
||||||
|
} gpIterData;
|
||||||
|
|
||||||
|
static void eevee_gpencil_layer_cache_populate(bGPDlayer *gpl,
|
||||||
|
bGPDframe *UNUSED(gpf),
|
||||||
|
bGPDstroke *UNUSED(gps),
|
||||||
|
void *thunk)
|
||||||
|
{
|
||||||
|
gpIterData *iter = (gpIterData *)thunk;
|
||||||
|
bGPdata *gpd = (bGPdata *)iter->ob->data;
|
||||||
|
|
||||||
|
const bool is_screenspace = (gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0;
|
||||||
|
const bool is_stroke_order_3d = (gpd->draw_mode == GP_DRAWMODE_3D);
|
||||||
|
|
||||||
|
float object_scale = mat4_to_scale(iter->ob->obmat);
|
||||||
|
/* Negate thickness sign to tag that strokes are in screen space.
|
||||||
|
* Convert to world units (by default, 1 meter = 2000 px). */
|
||||||
|
float thickness_scale = (is_screenspace) ? -1.0f : (gpd->pixfactor / 2000.0f);
|
||||||
|
|
||||||
|
DRWShadingGroup *grp = iter->stroke_shadow_grp = DRW_shgroup_create_sub(iter->stroke_shadow_grp);
|
||||||
|
DRW_shgroup_uniform_bool_copy(grp, "strokeOrder3d", is_stroke_order_3d);
|
||||||
|
DRW_shgroup_uniform_vec2_copy(grp, "sizeViewportInv", DRW_viewport_invert_size_get());
|
||||||
|
DRW_shgroup_uniform_vec2_copy(grp, "sizeViewport", DRW_viewport_size_get());
|
||||||
|
DRW_shgroup_uniform_float_copy(grp, "thicknessScale", object_scale);
|
||||||
|
DRW_shgroup_uniform_float_copy(grp, "thicknessOffset", (float)gpl->line_change);
|
||||||
|
DRW_shgroup_uniform_float_copy(grp, "thicknessWorldScale", thickness_scale);
|
||||||
|
DRW_shgroup_uniform_vec4_copy(grp, "gpDepthPlane", iter->plane);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void eevee_gpencil_stroke_cache_populate(bGPDlayer *gpl,
|
||||||
|
bGPDframe *UNUSED(gpf),
|
||||||
|
bGPDstroke *gps,
|
||||||
|
void *thunk)
|
||||||
|
{
|
||||||
|
gpIterData *iter = (gpIterData *)thunk;
|
||||||
|
|
||||||
|
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(iter->ob, gps->mat_nr + 1);
|
||||||
|
|
||||||
|
const bool cast_layer_shadows = (gpl->flag & GP_LAYER_CAST_SHADOWS) != 0;
|
||||||
|
const bool cast_material_shadows = (gp_style->flag & GP_MATERIAL_CAST_SHADOWS) != 0;
|
||||||
|
const bool simplify_fill = iter->pd->gpencil_simplify_fill;
|
||||||
|
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
||||||
|
const bool show_stroke = (gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0;
|
||||||
|
const bool show_fill = (!simplify_fill) && (gps->tot_triangles > 0) &&
|
||||||
|
(gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0;
|
||||||
|
|
||||||
|
if ((hide_material) || (!cast_layer_shadows) || (!cast_material_shadows)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_fill) {
|
||||||
|
struct GPUBatch *geom = DRW_cache_gpencil_fills_get(iter->ob, iter->cfra);
|
||||||
|
int vfirst = gps->runtime.fill_start * 3;
|
||||||
|
int vcount = gps->tot_triangles * 3;
|
||||||
|
DRW_shgroup_call_range(iter->fill_shadow_grp, iter->ob, geom, vfirst, vcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_stroke) {
|
||||||
|
struct GPUBatch *geom = DRW_cache_gpencil_strokes_get(iter->ob, iter->cfra);
|
||||||
|
/* Start one vert before to have gl_InstanceID > 0 (see shader). */
|
||||||
|
int vfirst = gps->runtime.stroke_start - 1;
|
||||||
|
/* Include "potential" cyclic vertex and start adj vertex (see shader). */
|
||||||
|
int vcount = gps->totpoints + 1 + 1;
|
||||||
|
DRW_shgroup_call_instance_range(iter->stroke_shadow_grp, iter->ob, geom, vfirst, vcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEVEE_gpencil_cache_populate(EEVEE_Data *vedata,
|
||||||
|
EEVEE_ViewLayerData *sldata,
|
||||||
|
Object *ob,
|
||||||
|
bool *cast_shadow)
|
||||||
|
{
|
||||||
|
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
||||||
|
EeveeMaterialCache matcache = eevee_material_cache_get(vedata, sldata, ob, 0, false, true);
|
||||||
|
|
||||||
|
gpIterData iter = {
|
||||||
|
.ob = ob,
|
||||||
|
.pd = pd,
|
||||||
|
.stroke_shadow_grp = NULL,
|
||||||
|
.fill_shadow_grp = NULL,
|
||||||
|
.cfra = pd->cfra,
|
||||||
|
};
|
||||||
|
|
||||||
|
// if (gpd->draw_mode == GP_DRAWMODE_2D) {
|
||||||
|
// gpencil_depth_plane(ob, iter.plane);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (matcache.shadow_grp) {
|
||||||
|
iter.stroke_shadow_grp = matcache.shadow_grp;
|
||||||
|
iter.fill_shadow_grp = DRW_shgroup_create_sub(matcache.shadow_grp);
|
||||||
|
|
||||||
|
*matcache.shadow_grp_p = matcache.shadow_grp = iter.fill_shadow_grp;
|
||||||
|
*cast_shadow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool any_material_visible = matcache.shadow_grp != NULL;
|
||||||
|
if (any_material_visible) {
|
||||||
|
BKE_gpencil_visible_stroke_iter(NULL,
|
||||||
|
ob,
|
||||||
|
eevee_gpencil_layer_cache_populate,
|
||||||
|
eevee_gpencil_stroke_cache_populate,
|
||||||
|
&iter,
|
||||||
|
false,
|
||||||
|
pd->cfra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
||||||
{
|
{
|
||||||
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
EEVEE_PrivateData *pd = vedata->stl->g_data;
|
||||||
|
@@ -176,7 +176,7 @@ enum {
|
|||||||
VAR_MAT_MESH = (1 << 0),
|
VAR_MAT_MESH = (1 << 0),
|
||||||
VAR_MAT_VOLUME = (1 << 1),
|
VAR_MAT_VOLUME = (1 << 1),
|
||||||
VAR_MAT_HAIR = (1 << 2),
|
VAR_MAT_HAIR = (1 << 2),
|
||||||
/* VAR_MAT_PROBE = (1 << 3), UNUSED */
|
VAR_MAT_GPENCIL = (1 << 3),
|
||||||
VAR_MAT_BLEND = (1 << 4),
|
VAR_MAT_BLEND = (1 << 4),
|
||||||
VAR_MAT_LOOKDEV = (1 << 5),
|
VAR_MAT_LOOKDEV = (1 << 5),
|
||||||
VAR_MAT_HOLDOUT = (1 << 6),
|
VAR_MAT_HOLDOUT = (1 << 6),
|
||||||
@@ -1066,6 +1066,11 @@ typedef struct EEVEE_PrivateData {
|
|||||||
/** For rendering planar reflections. */
|
/** For rendering planar reflections. */
|
||||||
struct DRWView *planar_views[MAX_PLANAR];
|
struct DRWView *planar_views[MAX_PLANAR];
|
||||||
|
|
||||||
|
/** For rendering Gpencil Objects. */
|
||||||
|
int cfra;
|
||||||
|
/** Simplify grease pencil fill. */
|
||||||
|
bool gpencil_simplify_fill;
|
||||||
|
|
||||||
int render_timesteps;
|
int render_timesteps;
|
||||||
int render_sample_count_per_timestep;
|
int render_sample_count_per_timestep;
|
||||||
} EEVEE_PrivateData; /* Transient data */
|
} EEVEE_PrivateData; /* Transient data */
|
||||||
@@ -1113,6 +1118,10 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
|
|||||||
EEVEE_ViewLayerData *sldata,
|
EEVEE_ViewLayerData *sldata,
|
||||||
Object *ob,
|
Object *ob,
|
||||||
bool *cast_shadow);
|
bool *cast_shadow);
|
||||||
|
void EEVEE_gpencil_cache_populate(EEVEE_Data *vedata,
|
||||||
|
EEVEE_ViewLayerData *sldata,
|
||||||
|
Object *ob,
|
||||||
|
bool *cast_shadow);
|
||||||
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
|
||||||
void EEVEE_materials_free(void);
|
void EEVEE_materials_free(void);
|
||||||
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
|
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
|
||||||
|
@@ -256,6 +256,9 @@ void EEVEE_render_cache(void *vedata,
|
|||||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||||
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
|
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
|
||||||
}
|
}
|
||||||
|
else if (ob->type == OB_GPENCIL) {
|
||||||
|
EEVEE_gpencil_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||||
|
}
|
||||||
else if (ob->type == OB_LIGHTPROBE) {
|
else if (ob->type == OB_LIGHTPROBE) {
|
||||||
EEVEE_lightprobes_cache_add(sldata, vedata, ob);
|
EEVEE_lightprobes_cache_add(sldata, vedata, ob);
|
||||||
}
|
}
|
||||||
|
@@ -184,6 +184,7 @@ extern char datatoc_common_hair_lib_glsl[];
|
|||||||
extern char datatoc_common_math_lib_glsl[];
|
extern char datatoc_common_math_lib_glsl[];
|
||||||
extern char datatoc_common_math_geom_lib_glsl[];
|
extern char datatoc_common_math_geom_lib_glsl[];
|
||||||
extern char datatoc_common_view_lib_glsl[];
|
extern char datatoc_common_view_lib_glsl[];
|
||||||
|
extern char datatoc_gpencil_common_lib_glsl[];
|
||||||
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
|
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
|
||||||
|
|
||||||
extern char datatoc_ambient_occlusion_lib_glsl[];
|
extern char datatoc_ambient_occlusion_lib_glsl[];
|
||||||
@@ -290,6 +291,7 @@ static void eevee_shader_library_ensure(void)
|
|||||||
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
|
||||||
|
DRW_SHADER_LIB_ADD(e_data.lib, gpencil_common_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, random_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, random_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib);
|
||||||
DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib);
|
DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib);
|
||||||
@@ -1358,6 +1360,9 @@ static char *eevee_get_defines(int options)
|
|||||||
if ((options & VAR_MAT_HAIR) != 0) {
|
if ((options & VAR_MAT_HAIR) != 0) {
|
||||||
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
|
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
|
||||||
}
|
}
|
||||||
|
if ((options & VAR_MAT_GPENCIL) != 0) {
|
||||||
|
BLI_dynstr_append(ds, "#define GPENCIL_SHADER\n");
|
||||||
|
}
|
||||||
if ((options & VAR_WORLD_PROBE) != 0) {
|
if ((options & VAR_WORLD_PROBE) != 0) {
|
||||||
BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
|
BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
|
|
||||||
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
||||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(gpencil_common_lib.glsl)
|
||||||
#ifndef HAIR_SHADER
|
|
||||||
in vec3 pos;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
@@ -23,8 +20,11 @@ void main()
|
|||||||
time,
|
time,
|
||||||
thickness,
|
thickness,
|
||||||
thick_time);
|
thick_time);
|
||||||
|
#elif defined(GPENCIL_SHADER)
|
||||||
|
/* TODO */
|
||||||
|
vec3 worldPosition = vec3(0.0);
|
||||||
#else
|
#else
|
||||||
vec3 worldPosition = point_object_to_world(pos);
|
vec3 worldPosition = point_object_to_world(pos.xyz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl_Position = point_world_to_ndc(worldPosition);
|
gl_Position = point_world_to_ndc(worldPosition);
|
||||||
@@ -32,4 +32,8 @@ void main()
|
|||||||
#ifdef CLIP_PLANES
|
#ifdef CLIP_PLANES
|
||||||
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
|
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(GPENCIL_SHADER)
|
||||||
|
gpencil_vertex();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,9 @@
|
|||||||
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
|
||||||
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
|
||||||
#pragma BLENDER_REQUIRE(surface_lib.glsl)
|
#pragma BLENDER_REQUIRE(surface_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(gpencil_common_lib.glsl)
|
||||||
|
|
||||||
#ifndef HAIR_SHADER
|
#if !defined(HAIR_SHADER) && !defined(GPENCIL_SHADER)
|
||||||
in vec3 pos;
|
|
||||||
in vec3 nor;
|
in vec3 nor;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -31,12 +31,21 @@ void main()
|
|||||||
hairThickTime);
|
hairThickTime);
|
||||||
worldNormal = cross(hairTangent, binor);
|
worldNormal = cross(hairTangent, binor);
|
||||||
vec3 world_pos = pos;
|
vec3 world_pos = pos;
|
||||||
|
#elif defined(GPENCIL_SHADER)
|
||||||
|
/* TODO */
|
||||||
|
vec3 pos = vec3(0.0);
|
||||||
|
vec3 nor = vec3(1.0);
|
||||||
|
vec3 world_pos = pos.xyz;
|
||||||
#else
|
#else
|
||||||
vec3 world_pos = point_object_to_world(pos);
|
vec3 world_pos = point_object_to_world(pos.xyz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gl_Position = point_world_to_ndc(world_pos);
|
gl_Position = point_world_to_ndc(world_pos);
|
||||||
|
|
||||||
|
#if defined(GPENCIL_SHADER)
|
||||||
|
gpencil_vertex();
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Used for planar reflections */
|
/* Used for planar reflections */
|
||||||
gl_ClipDistance[0] = dot(vec4(world_pos, 1.0), clipPlanes[0]);
|
gl_ClipDistance[0] = dot(vec4(world_pos, 1.0), clipPlanes[0]);
|
||||||
|
|
||||||
@@ -54,7 +63,7 @@ void main()
|
|||||||
# ifdef HAIR_SHADER
|
# ifdef HAIR_SHADER
|
||||||
pos = hair_get_strand_pos();
|
pos = hair_get_strand_pos();
|
||||||
# endif
|
# endif
|
||||||
pass_attr(pos, NormalMatrix, ModelMatrixInverse);
|
pass_attr(pos.xyz, NormalMatrix, ModelMatrixInverse);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -149,7 +149,7 @@ void blend_mode_output(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IN_OUT ShaderStageInterface
|
IN_OUT GpencilShaderStageInterface
|
||||||
{
|
{
|
||||||
vec4 finalColorMul;
|
vec4 finalColorMul;
|
||||||
vec4 finalColorAdd;
|
vec4 finalColorAdd;
|
||||||
|
@@ -550,6 +550,8 @@ typedef enum eGPDlayer_Flag {
|
|||||||
GP_LAYER_FRAMELOCK = (1 << 6),
|
GP_LAYER_FRAMELOCK = (1 << 6),
|
||||||
/* don't render xray (which is default) */
|
/* don't render xray (which is default) */
|
||||||
GP_LAYER_NO_XRAY = (1 << 7),
|
GP_LAYER_NO_XRAY = (1 << 7),
|
||||||
|
/* Show render shadows */
|
||||||
|
GP_LAYER_CAST_SHADOWS = (1 << 8),
|
||||||
/* "volumetric" strokes */
|
/* "volumetric" strokes */
|
||||||
GP_LAYER_VOLUMETRIC = (1 << 10),
|
GP_LAYER_VOLUMETRIC = (1 << 10),
|
||||||
/* Use Scene lights */
|
/* Use Scene lights */
|
||||||
|
@@ -137,6 +137,8 @@ typedef enum eMaterialGPencilStyle_Flag {
|
|||||||
GP_MATERIAL_IS_STROKE_HOLDOUT = (1 << 13),
|
GP_MATERIAL_IS_STROKE_HOLDOUT = (1 << 13),
|
||||||
/* Material used as fill masking. */
|
/* Material used as fill masking. */
|
||||||
GP_MATERIAL_IS_FILL_HOLDOUT = (1 << 14),
|
GP_MATERIAL_IS_FILL_HOLDOUT = (1 << 14),
|
||||||
|
/* Show Eevee shadows */
|
||||||
|
GP_MATERIAL_CAST_SHADOWS = (1 << 15),
|
||||||
} eMaterialGPencilStyle_Flag;
|
} eMaterialGPencilStyle_Flag;
|
||||||
|
|
||||||
typedef enum eMaterialGPencilStyle_Mode {
|
typedef enum eMaterialGPencilStyle_Mode {
|
||||||
|
@@ -2215,6 +2215,11 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
|||||||
prop, "Use Lights", "Enable the use of lights on stroke and fill materials");
|
prop, "Use Lights", "Enable the use of lights on stroke and fill materials");
|
||||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_CAST_SHADOWS);
|
||||||
|
RNA_def_property_ui_text(prop, "Cast Shadows", "Show shadows produced by grease pencil object");
|
||||||
|
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||||
|
|
||||||
/* solo mode: Only display frames with keyframe */
|
/* solo mode: Only display frames with keyframe */
|
||||||
prop = RNA_def_property(srna, "use_solo_mode", PROP_BOOLEAN, PROP_NONE);
|
prop = RNA_def_property(srna, "use_solo_mode", PROP_BOOLEAN, PROP_NONE);
|
||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SOLO_MODE);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SOLO_MODE);
|
||||||
|
@@ -596,6 +596,11 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
|
|||||||
RNA_def_property_ui_text(prop, "Show Fill", "Show stroke fills of this material");
|
RNA_def_property_ui_text(prop, "Show Fill", "Show stroke fills of this material");
|
||||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
|
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "use_cast_shadows", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MATERIAL_CAST_SHADOWS);
|
||||||
|
RNA_def_property_ui_text(prop, "Cast Shadows", "Show shadows produced by grease pencil object");
|
||||||
|
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update");
|
||||||
|
|
||||||
/* Mode to align Dots and Boxes to drawing path and object rotation */
|
/* Mode to align Dots and Boxes to drawing path and object rotation */
|
||||||
prop = RNA_def_property(srna, "alignment_mode", PROP_ENUM, PROP_NONE);
|
prop = RNA_def_property(srna, "alignment_mode", PROP_ENUM, PROP_NONE);
|
||||||
RNA_def_property_enum_bitflag_sdna(prop, NULL, "alignment_mode");
|
RNA_def_property_enum_bitflag_sdna(prop, NULL, "alignment_mode");
|
||||||
|
Reference in New Issue
Block a user