WIP: GPv3: Switch back to the GPv2 render engine #118663
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
||||
|
@ -36,16 +37,18 @@
|
|||
/** \name Object
|
||||
* \{ */
|
||||
|
||||
GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
|
||||
GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd,
|
||||
Object *ob,
|
||||
const bool is_drawmode,
|
||||
const std::optional<blender::Bounds<float3>> bounds)
|
||||
{
|
||||
using namespace blender;
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
GPENCIL_tObject *tgp_ob = static_cast<GPENCIL_tObject *>(BLI_memblock_alloc(pd->gp_object_pool));
|
||||
|
||||
tgp_ob->layers.first = tgp_ob->layers.last = nullptr;
|
||||
tgp_ob->vfx.first = tgp_ob->vfx.last = nullptr;
|
||||
tgp_ob->camera_z = dot_v3v3(pd->camera_z_axis, ob->object_to_world().location());
|
||||
tgp_ob->is_drawmode3d = (gpd->draw_mode == GP_DRAWMODE_3D) || pd->draw_depth_only;
|
||||
tgp_ob->is_drawmode3d = is_drawmode || pd->draw_depth_only;
|
||||
tgp_ob->object_scale = mat4_to_scale(ob->object_to_world().ptr());
|
||||
|
||||
/* Check if any material with holdout flag enabled. */
|
||||
|
@ -66,8 +69,6 @@ GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob)
|
|||
* strokes not aligned with the object axes. Maybe we could try to
|
||||
* compute the minimum axis of all strokes. But this would be more
|
||||
* computationally heavy and should go into the GPData evaluation. */
|
||||
const std::optional<Bounds<float3>> bounds = BKE_gpencil_data_minmax(gpd).value_or(
|
||||
Bounds(float3(0)));
|
||||
float3 size = (bounds->max - bounds->min) * 0.5f;
|
||||
float3 center = math::midpoint(bounds->min, bounds->max);
|
||||
/* Convert bbox to matrix */
|
||||
|
@ -203,6 +204,28 @@ static float gpencil_layer_final_opacity_get(const GPENCIL_PrivateData *pd,
|
|||
return gpl->opacity;
|
||||
}
|
||||
|
||||
static float grease_pencil_layer_final_opacity_get(const GPENCIL_PrivateData *pd,
|
||||
const Object *ob,
|
||||
const GreasePencil &grease_pencil,
|
||||
const blender::bke::greasepencil::Layer &layer)
|
||||
{
|
||||
const bool is_obact = ((pd->obact) && (pd->obact == ob));
|
||||
const bool is_fade = (pd->fade_layer_opacity > -1.0f) && (is_obact) &&
|
||||
grease_pencil.is_layer_active(&layer);
|
||||
|
||||
/* Defines layer opacity. For active object depends of layer opacity factor, and
|
||||
* for no active object, depends if the fade grease pencil objects option is enabled. */
|
||||
if (!pd->is_render) {
|
||||
if (is_obact && is_fade) {
|
||||
return layer.opacity * pd->fade_layer_opacity;
|
||||
}
|
||||
if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) {
|
||||
return layer.opacity * pd->fade_gp_object_opacity;
|
||||
}
|
||||
}
|
||||
return layer.opacity;
|
||||
}
|
||||
|
||||
static void gpencil_layer_final_tint_and_alpha_get(const GPENCIL_PrivateData *pd,
|
||||
const bGPdata *gpd,
|
||||
const bGPDlayer *gpl,
|
||||
|
@ -253,6 +276,20 @@ static void gpencil_layer_random_color_get(const Object *ob,
|
|||
hsv_to_rgb_v(hsv, r_color);
|
||||
}
|
||||
|
||||
static void grease_pencil_layer_random_color_get(const Object *ob,
|
||||
const blender::bke::greasepencil::Layer &layer,
|
||||
float r_color[3])
|
||||
{
|
||||
const float hsv_saturation = 0.7f;
|
||||
const float hsv_value = 0.6f;
|
||||
|
||||
uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
|
||||
uint gpl_hash = BLI_ghashutil_strhash_p_murmur(layer.name().c_str());
|
||||
float hue = BLI_hash_int_01(ob_hash * gpl_hash);
|
||||
const float hsv[3] = {hue, hsv_saturation, hsv_value};
|
||||
hsv_to_rgb_v(hsv, r_color);
|
||||
}
|
||||
|
||||
GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
||||
const Object *ob,
|
||||
const bGPDlayer *gpl,
|
||||
|
@ -433,4 +470,173 @@ GPENCIL_tLayer *gpencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int number)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
||||
const Object *ob,
|
||||
const blender::bke::greasepencil::Layer &layer,
|
||||
std::optional<int> /*onion_id*/,
|
||||
GPENCIL_tObject *tgp_ob)
|
||||
|
||||
{
|
||||
const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
|
||||
const bool is_in_front = (ob->dtx & OB_DRAW_IN_FRONT);
|
||||
/* Grease Pencil 3 doesn't have this. */
|
||||
const bool is_screenspace = false;
|
||||
const bool override_vertcol = (pd->v3d_color_type != -1);
|
||||
const bool is_vert_col_mode = (pd->v3d_color_type == V3D_SHADING_VERTEX_COLOR) ||
|
||||
(ob->mode == OB_MODE_VERTEX_PAINT) || pd->is_render;
|
||||
/* const bool is_viewlayer_render = pd->is_render && (gpl->viewlayername[0] != '\0') &&
|
||||
* STREQ(pd->view_layer->name, gpl->viewlayername); */
|
||||
// const bool is_viewlayer_render = false;
|
||||
// const bool disable_masks_render = is_viewlayer_render &&
|
||||
// (layer.base.flag & GP_LAYER_DISABLE_MASKS_IN_VIEWLAYER);
|
||||
/* bool is_masked = disable_masks_render ? false :
|
||||
(gpl->flag & GP_LAYER_USE_MASK) &&
|
||||
!BLI_listbase_is_empty(&gpl->mask_layers); */
|
||||
bool is_masked = false;
|
||||
|
||||
float vert_col_opacity = (override_vertcol) ?
|
||||
(is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
|
||||
pd->vertex_paint_opacity;
|
||||
/* Negate thickness sign to tag that strokes are in screen space.
|
||||
* Convert to world units (by default, 1 meter = 2000 pixels). */
|
||||
float thickness_scale = (is_screenspace) ? -1.0f : GPENCIL_PIXEL_FACTOR;
|
||||
float layer_opacity = grease_pencil_layer_final_opacity_get(pd, ob, grease_pencil, layer);
|
||||
float4 layer_tint(0.0f);
|
||||
float layer_alpha = pd->xray_alpha;
|
||||
/* TODO: Onion skinning! */
|
||||
// gpencil_layer_final_tint_and_alpha_get(pd, gpd, gpl, gpf, layer_tint, &layer_alpha);
|
||||
|
||||
/* Create the new layer descriptor. */
|
||||
GPENCIL_tLayer *tgp_layer = static_cast<GPENCIL_tLayer *>(BLI_memblock_alloc(pd->gp_layer_pool));
|
||||
BLI_LINKS_APPEND(&tgp_ob->layers, tgp_layer);
|
||||
tgp_layer->layer_id = *grease_pencil.get_layer_index(layer);
|
||||
tgp_layer->mask_bits = nullptr;
|
||||
tgp_layer->mask_invert_bits = nullptr;
|
||||
tgp_layer->blend_ps = nullptr;
|
||||
|
||||
/* Masking: Go through mask list and extract valid masks in a bitmap. */
|
||||
// if (is_masked) {
|
||||
// bool valid_mask = false;
|
||||
// /* WARNING: only #GP_MAX_MASKBITS amount of bits.
|
||||
// * TODO(fclem): Find a better system without any limitation. */
|
||||
// tgp_layer->mask_bits = static_cast<BLI_bitmap *>(BLI_memblock_alloc(pd->gp_maskbit_pool));
|
||||
// tgp_layer->mask_invert_bits = static_cast<BLI_bitmap *>(
|
||||
// BLI_memblock_alloc(pd->gp_maskbit_pool));
|
||||
// BLI_bitmap_set_all(tgp_layer->mask_bits, false, GP_MAX_MASKBITS);
|
||||
|
||||
// LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
|
||||
// bGPDlayer *gpl_mask = BKE_gpencil_layer_named_get(gpd, mask->name);
|
||||
// if (gpl_mask && (gpl_mask != gpl) && ((gpl_mask->flag & GP_LAYER_HIDE) == 0) &&
|
||||
// ((mask->flag & GP_MASK_HIDE) == 0))
|
||||
// {
|
||||
// int index = BLI_findindex(&gpd->layers, gpl_mask);
|
||||
// if (index < GP_MAX_MASKBITS) {
|
||||
// const bool invert = (mask->flag & GP_MASK_INVERT) != 0;
|
||||
// BLI_BITMAP_SET(tgp_layer->mask_bits, index, true);
|
||||
// BLI_BITMAP_SET(tgp_layer->mask_invert_bits, index, invert);
|
||||
// valid_mask = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (valid_mask) {
|
||||
// pd->use_mask_fb = true;
|
||||
// }
|
||||
// else {
|
||||
// tgp_layer->mask_bits = nullptr;
|
||||
// }
|
||||
// is_masked = valid_mask;
|
||||
// }
|
||||
|
||||
/* Blending: Force blending for masked layer. */
|
||||
if (is_masked || (layer.blend_mode != GP_LAYER_BLEND_NONE) || (layer_opacity < 1.0f)) {
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL;
|
||||
switch (layer.blend_mode) {
|
||||
case GP_LAYER_BLEND_NONE:
|
||||
state |= DRW_STATE_BLEND_ALPHA_PREMUL;
|
||||
break;
|
||||
case GP_LAYER_BLEND_ADD:
|
||||
state |= DRW_STATE_BLEND_ADD_FULL;
|
||||
break;
|
||||
case GP_LAYER_BLEND_SUBTRACT:
|
||||
state |= DRW_STATE_BLEND_SUB;
|
||||
break;
|
||||
case GP_LAYER_BLEND_MULTIPLY:
|
||||
case GP_LAYER_BLEND_DIVIDE:
|
||||
case GP_LAYER_BLEND_HARDLIGHT:
|
||||
state |= DRW_STATE_BLEND_MUL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ELEM(layer.blend_mode, GP_LAYER_BLEND_SUBTRACT, GP_LAYER_BLEND_HARDLIGHT)) {
|
||||
/* For these effect to propagate, we need a signed floating point buffer. */
|
||||
pd->use_signed_fb = true;
|
||||
}
|
||||
|
||||
tgp_layer->blend_ps = DRW_pass_create("GPencil Blend Layer", state);
|
||||
|
||||
GPUShader *sh = GPENCIL_shader_layer_blend_get();
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(sh, tgp_layer->blend_ps);
|
||||
DRW_shgroup_uniform_int_copy(grp, "blendMode", layer.blend_mode);
|
||||
DRW_shgroup_uniform_float_copy(grp, "blendOpacity", layer_opacity);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "colorBuf", &pd->color_layer_tx);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "revealBuf", &pd->reveal_layer_tx);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "maskBuf", (is_masked) ? &pd->mask_tx : &pd->dummy_tx);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
|
||||
|
||||
if (layer.blend_mode == GP_LAYER_BLEND_HARDLIGHT) {
|
||||
/* We cannot do custom blending on Multi-Target frame-buffers.
|
||||
* Workaround by doing 2 passes. */
|
||||
grp = DRW_shgroup_create(sh, tgp_layer->blend_ps);
|
||||
DRW_shgroup_state_disable(grp, DRW_STATE_BLEND_MUL);
|
||||
DRW_shgroup_state_enable(grp, DRW_STATE_BLEND_ADD_FULL);
|
||||
DRW_shgroup_uniform_int_copy(grp, "blendMode", 999);
|
||||
DRW_shgroup_call_procedural_triangles(grp, nullptr, 1);
|
||||
}
|
||||
|
||||
pd->use_layer_fb = true;
|
||||
}
|
||||
|
||||
/* Geometry pass */
|
||||
{
|
||||
GPUTexture *depth_tex = (is_in_front) ? pd->dummy_tx : pd->scene_depth_tx;
|
||||
GPUTexture **mask_tex = (is_masked) ? &pd->mask_tx : &pd->dummy_tx;
|
||||
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND_ALPHA_PREMUL;
|
||||
/* For 2D mode, we render all strokes with uniform depth (increasing with stroke id). */
|
||||
state |= tgp_ob->is_drawmode3d ? DRW_STATE_DEPTH_LESS_EQUAL : DRW_STATE_DEPTH_GREATER;
|
||||
/* Always write stencil. Only used as optimization for blending. */
|
||||
state |= DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
|
||||
|
||||
tgp_layer->geom_ps = DRW_pass_create("GPencil Layer", state);
|
||||
|
||||
GPUShader *sh = GPENCIL_shader_geometry_get();
|
||||
DRWShadingGroup *grp = tgp_layer->base_shgrp = DRW_shgroup_create(sh, tgp_layer->geom_ps);
|
||||
|
||||
DRW_shgroup_uniform_texture(grp, "gpSceneDepthTexture", depth_tex);
|
||||
DRW_shgroup_uniform_texture_ref(grp, "gpMaskTexture", mask_tex);
|
||||
DRW_shgroup_uniform_vec3_copy(grp, "gpNormal", tgp_ob->plane_normal);
|
||||
DRW_shgroup_uniform_bool_copy(grp, "gpStrokeOrder3d", tgp_ob->is_drawmode3d);
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpThicknessScale", tgp_ob->object_scale);
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpThicknessOffset", 0.0f);
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpThicknessWorldScale", thickness_scale);
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpVertexColorOpacity", vert_col_opacity);
|
||||
|
||||
/* If random color type, need color by layer. */
|
||||
float gpl_color[4];
|
||||
copy_v4_v4(gpl_color, layer_tint);
|
||||
if (pd->v3d_color_type == V3D_SHADING_RANDOM_COLOR) {
|
||||
grease_pencil_layer_random_color_get(ob, layer, gpl_color);
|
||||
gpl_color[3] = 1.0f;
|
||||
}
|
||||
DRW_shgroup_uniform_vec4_copy(grp, "gpLayerTint", gpl_color);
|
||||
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpLayerOpacity", layer_alpha);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
}
|
||||
|
||||
return tgp_layer;
|
||||
}
|
||||
/** \} */
|
||||
|
|
|
@ -157,7 +157,10 @@ static MaterialGPencilStyle *gpencil_viewport_material_overrides(
|
|||
return gp_style;
|
||||
}
|
||||
|
||||
GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Object *ob, int *ofs)
|
||||
GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd,
|
||||
Object *ob,
|
||||
int *ofs,
|
||||
const bool is_vertex_mode)
|
||||
{
|
||||
GPENCIL_MaterialPool *matpool = pd->last_material_pool;
|
||||
|
||||
|
@ -175,10 +178,8 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje
|
|||
}
|
||||
|
||||
/* Force vertex color in solid mode with vertex paint mode. Same behavior as meshes. */
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
int color_type = (pd->v3d_color_type != -1 && GPENCIL_VERTEX_MODE(gpd)) ?
|
||||
V3D_SHADING_VERTEX_COLOR :
|
||||
pd->v3d_color_type;
|
||||
int color_type = (pd->v3d_color_type != -1 && is_vertex_mode) ? V3D_SHADING_VERTEX_COLOR :
|
||||
pd->v3d_color_type;
|
||||
const eV3DShadingLightingMode lighting_mode = eV3DShadingLightingMode(
|
||||
(pd->v3d != nullptr) ? eV3DShadingLightingMode(pd->v3d->shading.light) :
|
||||
V3D_LIGHTING_STUDIO);
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "DRW_render.hh"
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_bounds.hh"
|
||||
|
||||
#include "BKE_grease_pencil.hh"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
|
@ -322,7 +325,10 @@ typedef struct GPENCIL_PrivateData {
|
|||
/* geometry batch cache functions */
|
||||
struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra);
|
||||
|
||||
GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob);
|
||||
GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd,
|
||||
Object *ob,
|
||||
bool is_drawmode,
|
||||
std::optional<blender::Bounds<float3>> bounds);
|
||||
void gpencil_object_cache_sort(GPENCIL_PrivateData *pd);
|
||||
|
||||
GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
||||
|
@ -332,12 +338,20 @@ GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
|||
GPENCIL_tObject *tgp_ob);
|
||||
GPENCIL_tLayer *gpencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int number);
|
||||
|
||||
GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
||||
const Object *ob,
|
||||
const blender::bke::greasepencil::Layer &layer,
|
||||
std::optional<int> onion_id,
|
||||
GPENCIL_tObject *tgp_ob);
|
||||
/**
|
||||
* Creates a linked list of material pool containing all materials assigned for a given object.
|
||||
* We merge the material pools together if object does not contain a huge amount of materials.
|
||||
* Also return an offset to the first material of the object in the UBO.
|
||||
*/
|
||||
GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Object *ob, int *ofs);
|
||||
GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd,
|
||||
Object *ob,
|
||||
int *ofs,
|
||||
bool is_vertex_mode);
|
||||
void gpencil_material_resources_get(GPENCIL_MaterialPool *first_pool,
|
||||
int mat_id,
|
||||
struct GPUTexture **r_tex_stroke,
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
#include "DRW_engine.hh"
|
||||
#include "DRW_render.hh"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_gpencil_modifier_legacy.h"
|
||||
#include "BKE_grease_pencil.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
|
@ -22,6 +26,7 @@
|
|||
#include "BLI_link_utils.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_memblock.h"
|
||||
#include "BLI_virtual_array.hh"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
|
@ -35,6 +40,7 @@
|
|||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#include "ED_grease_pencil.hh"
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_view3d.hh"
|
||||
|
||||
|
@ -113,8 +119,10 @@ void GPENCIL_engine_init(void *ved)
|
|||
|
||||
stl->pd->v3d_color_type = (v3d->shading.type == OB_SOLID) ? v3d->shading.color_type : -1;
|
||||
/* Special case: If Vertex Paint mode, use always Vertex mode. */
|
||||
if (v3d->shading.type == OB_SOLID && ctx->obact && ctx->obact->type == OB_GPENCIL_LEGACY &&
|
||||
ctx->obact->mode == OB_MODE_VERTEX_GPENCIL_LEGACY)
|
||||
if (v3d->shading.type == OB_SOLID && ctx->obact &&
|
||||
((ctx->obact->type == OB_GPENCIL_LEGACY &&
|
||||
ctx->obact->mode == OB_MODE_VERTEX_GPENCIL_LEGACY) ||
|
||||
(ctx->obact->type == OB_GREASE_PENCIL && ctx->obact->mode == OB_MODE_VERTEX_PAINT)))
|
||||
{
|
||||
stl->pd->v3d_color_type = V3D_SHADING_VERTEX_COLOR;
|
||||
}
|
||||
|
@ -559,7 +567,10 @@ static void gpencil_sbuffer_cache_populate_fast(GPENCIL_Data *vedata, gpIterPopu
|
|||
GPUTexture *depth_texture = iter->pd->scene_depth_tx;
|
||||
GPENCIL_tObject *last_tgp_ob = iter->pd->tobjects.last;
|
||||
/* Create another temp object that only contain the stroke. */
|
||||
iter->tgp_ob = gpencil_object_cache_add(iter->pd, iter->ob);
|
||||
const std::optional<blender::Bounds<float3>> bounds = BKE_gpencil_data_minmax(gpd).value_or(
|
||||
blender::Bounds(float3(0)));
|
||||
iter->tgp_ob = gpencil_object_cache_add(
|
||||
iter->pd, iter->ob, (gpd->draw_mode == GP_DRAWMODE_3D), bounds);
|
||||
/* Remove from the main list. */
|
||||
iter->pd->tobjects.last = last_tgp_ob;
|
||||
last_tgp_ob->next = nullptr;
|
||||
|
@ -602,16 +613,18 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
|
|||
}
|
||||
|
||||
if (ob->data && (ob->type == OB_GPENCIL_LEGACY) && (ob->dt >= OB_SOLID)) {
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
const std::optional<blender::Bounds<float3>> bounds = BKE_gpencil_data_minmax(gpd).value_or(
|
||||
blender::Bounds(float3(0)));
|
||||
gpIterPopulateData iter = {nullptr};
|
||||
iter.ob = ob;
|
||||
iter.pd = pd;
|
||||
iter.tgp_ob = gpencil_object_cache_add(pd, ob);
|
||||
iter.matpool = gpencil_material_pool_create(pd, ob, &iter.mat_ofs);
|
||||
iter.tgp_ob = gpencil_object_cache_add(pd, ob, (gpd->draw_mode == GP_DRAWMODE_3D), bounds);
|
||||
iter.matpool = gpencil_material_pool_create(pd, ob, &iter.mat_ofs, GPENCIL_VERTEX_MODE(gpd));
|
||||
iter.tex_fill = txl->dummy_texture;
|
||||
iter.tex_stroke = txl->dummy_texture;
|
||||
|
||||
/* Special case for rendering onion skin. */
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
bool do_onion = (!pd->is_render) ? pd->do_onion : (gpd->onion_flag & GP_ONION_GHOST_ALWAYS);
|
||||
gpd->runtime.playing = short(pd->playing);
|
||||
|
||||
|
@ -652,6 +665,182 @@ void GPENCIL_cache_populate(void *ved, Object *ob)
|
|||
gpencil_sbuffer_cache_populate_fast(vedata, &iter);
|
||||
}
|
||||
}
|
||||
else if (ob->data && (ob->type == OB_GREASE_PENCIL) && (ob->dt >= OB_SOLID)) {
|
||||
using namespace blender;
|
||||
using namespace blender::ed::greasepencil;
|
||||
using namespace blender::bke::greasepencil;
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
const bool is_vertex_mode = (ob->mode & OB_MODE_VERTEX_PAINT) != 0;
|
||||
const std::optional<blender::Bounds<float3>> bounds = grease_pencil.bounds_min_max_eval();
|
||||
|
||||
int mat_ofs = 0;
|
||||
GPENCIL_tObject *tgp_ob = gpencil_object_cache_add(pd, ob, false, bounds);
|
||||
GPENCIL_MaterialPool *matpool = gpencil_material_pool_create(pd, ob, &mat_ofs, is_vertex_mode);
|
||||
|
||||
GPUTexture *tex_fill = txl->dummy_texture;
|
||||
GPUTexture *tex_stroke = txl->dummy_texture;
|
||||
|
||||
GPUBatch *geom = draw::DRW_cache_grease_pencil_get(pd->scene, ob);
|
||||
DRWShadingGroup *grp;
|
||||
int vfirst = -1;
|
||||
int vcount = 0;
|
||||
|
||||
int t_offset = 0;
|
||||
int v_offset = 0;
|
||||
|
||||
const auto gpencil_drawcall_flush = [&]() {
|
||||
#if !DISABLE_BATCHING
|
||||
if (geom != nullptr) {
|
||||
DRW_shgroup_call_range(grp, ob, geom, vfirst, vcount);
|
||||
}
|
||||
#endif
|
||||
geom = nullptr;
|
||||
vfirst = -1;
|
||||
vcount = 0;
|
||||
};
|
||||
|
||||
const auto gpencil_drawcall_add = [&](GPUBatch *draw_geom, int v_first, int v_count) {
|
||||
#if DISABLE_BATCHING
|
||||
DRW_shgroup_call_range(grp, ob, geom, v_first, v_count);
|
||||
return;
|
||||
#endif
|
||||
int last = vfirst + vcount;
|
||||
/* Interrupt draw-call grouping if the sequence is not consecutive. */
|
||||
if ((draw_geom != geom) || (v_first - last > 0)) {
|
||||
gpencil_drawcall_flush();
|
||||
}
|
||||
geom = draw_geom;
|
||||
if (vfirst == -1) {
|
||||
vfirst = v_first;
|
||||
}
|
||||
vcount = v_first + v_count - vfirst;
|
||||
};
|
||||
|
||||
const Vector<DrawingInfo> drawings = retrieve_visible_drawings(*pd->scene, grease_pencil);
|
||||
const Span<const Layer *> layers = grease_pencil.layers();
|
||||
for (const DrawingInfo info : drawings) {
|
||||
const Layer &layer = *layers[info.layer_index];
|
||||
GPENCIL_tLayer *tgp_layer = grease_pencil_layer_cache_add(pd, ob, layer, {}, tgp_ob);
|
||||
|
||||
const bool use_lights = pd->use_lighting &&
|
||||
((layer.base.flag & GP_LAYER_TREE_NODE_USE_LIGHTS) != 0) &&
|
||||
(ob->dtx & OB_USE_GPENCIL_LIGHTS);
|
||||
|
||||
GPUUniformBuf *lights_ubo = (use_lights) ? pd->global_light_pool->ubo :
|
||||
pd->shadeless_light_pool->ubo;
|
||||
|
||||
GPUUniformBuf *ubo_mat;
|
||||
gpencil_material_resources_get(matpool, 0, nullptr, nullptr, &ubo_mat);
|
||||
|
||||
grp = tgp_layer->base_shgrp;
|
||||
DRW_shgroup_uniform_block(grp, "gp_lights", lights_ubo);
|
||||
DRW_shgroup_uniform_block(grp, "gp_materials", ubo_mat);
|
||||
DRW_shgroup_uniform_texture(grp, "gpFillTexture", tex_fill);
|
||||
DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", tex_stroke);
|
||||
DRW_shgroup_uniform_int_copy(grp, "gpMaterialOffset", mat_ofs);
|
||||
/* Since we don't use the sbuffer in GPv3, this is always 0. */
|
||||
DRW_shgroup_uniform_float_copy(grp, "gpStrokeIndexOffset", 0);
|
||||
DRW_shgroup_uniform_vec2_copy(grp, "viewportSize", DRW_viewport_size_get());
|
||||
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
bke::AttributeAccessor attributes = curves.attributes();
|
||||
VArray<int> stroke_materials = *attributes.lookup_or_default<int>(
|
||||
"material_index", bke::AttrDomain::Curve, 0);
|
||||
VArray<bool> cyclic = *attributes.lookup_or_default<bool>(
|
||||
"cyclic", bke::AttrDomain::Curve, false);
|
||||
for (const int stroke_i : curves.curves_range()) {
|
||||
const IndexRange points = points_by_curve[stroke_i];
|
||||
const int material_index = stroke_materials[stroke_i];
|
||||
MaterialGPencilStyle *gp_style = BKE_object_material_get(ob, material_index + 1)->gp_style;
|
||||
|
||||
const bool is_render = pd->is_render;
|
||||
bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
|
||||
/* bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0) ||
|
||||
* (!is_render && ((gps->flag & GP_STROKE_NOFILL) != 0)); */
|
||||
bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0) || !is_render;
|
||||
/* bool show_fill = (gps->tot_triangles > 0) &&
|
||||
* ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0) && (!pd->simplify_fill) &&
|
||||
* ((gps->flag & GP_STROKE_NOFILL) == 0); */
|
||||
bool show_fill = (points.size() >= 3) && ((gp_style->flag & GP_MATERIAL_FILL_SHOW) != 0) &&
|
||||
(!pd->simplify_fill);
|
||||
/* bool only_lines = !GPENCIL_PAINT_MODE(gpd) && gpl && gpf && gpl->actframe != gpf &&
|
||||
* pd->use_multiedit_lines_only; */
|
||||
bool only_lines = pd->use_multiedit_lines_only;
|
||||
/* bool is_onion = gpl && gpf && gpf->runtime.onion_id != 0; */
|
||||
bool is_onion = false;
|
||||
bool hide_onion = is_onion && ((gp_style->flag & GP_MATERIAL_HIDE_ONIONSKIN) != 0);
|
||||
if ((hide_material) || (!show_stroke && !show_fill) || (only_lines && !is_onion) ||
|
||||
(hide_onion))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
GPUUniformBuf *new_ubo_mat;
|
||||
GPUTexture *new_tex_fill = nullptr;
|
||||
GPUTexture *new_tex_stroke = nullptr;
|
||||
gpencil_material_resources_get(
|
||||
matpool, mat_ofs + material_index, &new_tex_stroke, &new_tex_fill, &new_ubo_mat);
|
||||
|
||||
bool resource_changed = (ubo_mat != new_ubo_mat) ||
|
||||
(new_tex_fill && (new_tex_fill != tex_fill)) ||
|
||||
(new_tex_stroke && (new_tex_stroke != tex_stroke));
|
||||
|
||||
if (resource_changed) {
|
||||
gpencil_drawcall_flush();
|
||||
|
||||
grp = DRW_shgroup_create_sub(grp);
|
||||
if (new_ubo_mat != ubo_mat) {
|
||||
DRW_shgroup_uniform_block(grp, "gp_materials", new_ubo_mat);
|
||||
ubo_mat = new_ubo_mat;
|
||||
}
|
||||
if (new_tex_fill) {
|
||||
DRW_shgroup_uniform_texture(grp, "gpFillTexture", new_tex_fill);
|
||||
tex_fill = new_tex_fill;
|
||||
}
|
||||
if (new_tex_stroke) {
|
||||
DRW_shgroup_uniform_texture(grp, "gpStrokeTexture", new_tex_stroke);
|
||||
tex_stroke = new_tex_stroke;
|
||||
}
|
||||
}
|
||||
|
||||
GPUBatch *new_geom = draw::DRW_cache_grease_pencil_get(pd->scene, ob);
|
||||
if (geom != new_geom) {
|
||||
gpencil_drawcall_flush();
|
||||
|
||||
GPUVertBuf *position_tx = draw::DRW_cache_gpencil_position_buffer_get(ob, pd->cfra);
|
||||
GPUVertBuf *color_tx = draw::DRW_cache_gpencil_color_buffer_get(ob, pd->cfra);
|
||||
DRW_shgroup_buffer_texture(grp, "gp_pos_tx", position_tx);
|
||||
DRW_shgroup_buffer_texture(grp, "gp_col_tx", color_tx);
|
||||
}
|
||||
|
||||
if (show_fill) {
|
||||
const int tot_triangles = points.size() - 2;
|
||||
t_offset += tot_triangles;
|
||||
int v_first = t_offset * 3;
|
||||
int v_count = tot_triangles * 3;
|
||||
gpencil_drawcall_add(new_geom, v_first, v_count);
|
||||
}
|
||||
|
||||
if (show_stroke) {
|
||||
v_offset += points.start();
|
||||
int v_first = v_offset * 3;
|
||||
bool is_cyclic = cyclic[stroke_i] && (points.size() > 2);
|
||||
int v_count = (points.size() + int(is_cyclic)) * 2 * 3;
|
||||
gpencil_drawcall_add(new_geom, v_first, v_count);
|
||||
}
|
||||
|
||||
/* Only needed by sbuffer. */
|
||||
/* stroke_index_last = gps->runtime.vertex_start + gps->totpoints + 1;*/
|
||||
}
|
||||
}
|
||||
|
||||
if (geom != nullptr) {
|
||||
DRW_shgroup_call_range(grp, ob, geom, vfirst, vcount);
|
||||
}
|
||||
|
||||
gpencil_vfx_cache_populate(vedata, ob, tgp_ob);
|
||||
}
|
||||
|
||||
if (ob->type == OB_LAMP && pd->use_lights) {
|
||||
gpencil_light_pool_populate(pd->global_light_pool, ob);
|
||||
|
@ -928,7 +1117,7 @@ void GPENCIL_draw_scene(void *ved)
|
|||
|
||||
/* Fade 3D objects. */
|
||||
if ((!pd->is_render) && (pd->fade_3d_object_opacity > -1.0f) && (pd->obact != nullptr) &&
|
||||
(pd->obact->type == OB_GPENCIL_LEGACY))
|
||||
(ELEM(pd->obact->type, OB_GPENCIL_LEGACY, OB_GREASE_PENCIL)))
|
||||
{
|
||||
float background_color[3];
|
||||
ED_view3d_background_color_get(pd->scene, pd->v3d, background_color);
|
||||
|
|
|
@ -1268,8 +1268,7 @@ static void drw_engines_enable(ViewLayer * /*view_layer*/,
|
|||
|
||||
drw_engines_enable_from_engine(engine_type, drawtype);
|
||||
if (gpencil_engine_needed && ((drawtype >= OB_SOLID) || !use_xray)) {
|
||||
use_drw_engine(U.experimental.use_grease_pencil_version3 ? &draw_engine_gpencil_next_type :
|
||||
&draw_engine_gpencil_type);
|
||||
use_drw_engine(&draw_engine_gpencil_type);
|
||||
}
|
||||
|
||||
if (is_compositor_enabled()) {
|
||||
|
@ -1299,16 +1298,12 @@ static void drw_engines_data_validate()
|
|||
* For slow exact check use `DRW_render_check_grease_pencil` */
|
||||
static bool drw_gpencil_engine_needed(Depsgraph *depsgraph, View3D *v3d)
|
||||
{
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
const bool exclude_gpencil_rendering = v3d ? (v3d->object_type_exclude_viewport &
|
||||
(1 << OB_GREASE_PENCIL)) != 0 :
|
||||
false;
|
||||
return (!exclude_gpencil_rendering) && DEG_id_type_any_exists(depsgraph, ID_GP);
|
||||
}
|
||||
const bool exclude_gpencil_rendering = v3d ? (v3d->object_type_exclude_viewport &
|
||||
(1 << OB_GPENCIL_LEGACY)) != 0 :
|
||||
false;
|
||||
return (!exclude_gpencil_rendering) && DEG_id_type_any_exists(depsgraph, ID_GD_LEGACY);
|
||||
const bool exclude_gpencil_rendering =
|
||||
v3d ? ((v3d->object_type_exclude_viewport & (1 << OB_GPENCIL_LEGACY)) != 0) ||
|
||||
((v3d->object_type_exclude_viewport & (1 << OB_GREASE_PENCIL)) != 0) :
|
||||
false;
|
||||
return (!exclude_gpencil_rendering) && (DEG_id_type_any_exists(depsgraph, ID_GD_LEGACY) ||
|
||||
DEG_id_type_any_exists(depsgraph, ID_GP));
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -1867,9 +1862,7 @@ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
|
|||
deg_iter_settings.depsgraph = depsgraph;
|
||||
deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
|
||||
DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) {
|
||||
if (ob->type == OB_GPENCIL_LEGACY ||
|
||||
(U.experimental.use_grease_pencil_version3 && ob->type == OB_GREASE_PENCIL))
|
||||
{
|
||||
if (ob->type == OB_GPENCIL_LEGACY || ob->type == OB_GREASE_PENCIL) {
|
||||
if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1884,9 +1877,7 @@ static void DRW_render_gpencil_to_image(RenderEngine *engine,
|
|||
RenderLayer *render_layer,
|
||||
const rcti *rect)
|
||||
{
|
||||
DrawEngineType *draw_engine = U.experimental.use_grease_pencil_version3 ?
|
||||
&draw_engine_gpencil_next_type :
|
||||
&draw_engine_gpencil_type;
|
||||
DrawEngineType *draw_engine = &draw_engine_gpencil_type;
|
||||
if (draw_engine->render_to_image) {
|
||||
ViewportEngineData *gpdata = DRW_view_data_engine_data_get_ensure(DST.view_data_active,
|
||||
draw_engine);
|
||||
|
@ -2479,8 +2470,7 @@ void DRW_draw_select_loop(Depsgraph *depsgraph,
|
|||
else if (!draw_surface) {
|
||||
/* grease pencil selection */
|
||||
if (drw_gpencil_engine_needed(depsgraph, v3d)) {
|
||||
use_drw_engine(U.experimental.use_grease_pencil_version3 ? &draw_engine_gpencil_next_type :
|
||||
&draw_engine_gpencil_type);
|
||||
use_drw_engine(&draw_engine_gpencil_type);
|
||||
}
|
||||
|
||||
drw_engines_enable_overlays();
|
||||
|
@ -2490,8 +2480,7 @@ void DRW_draw_select_loop(Depsgraph *depsgraph,
|
|||
drw_engines_enable_basic();
|
||||
/* grease pencil selection */
|
||||
if (drw_gpencil_engine_needed(depsgraph, v3d)) {
|
||||
use_drw_engine(U.experimental.use_grease_pencil_version3 ? &draw_engine_gpencil_next_type :
|
||||
&draw_engine_gpencil_type);
|
||||
use_drw_engine(&draw_engine_gpencil_type);
|
||||
}
|
||||
|
||||
drw_engines_enable_overlays();
|
||||
|
@ -2664,8 +2653,7 @@ void DRW_draw_depth_loop(Depsgraph *depsgraph,
|
|||
drw_manager_init(&DST, viewport, nullptr);
|
||||
|
||||
if (use_gpencil) {
|
||||
use_drw_engine(U.experimental.use_grease_pencil_version3 ? &draw_engine_gpencil_next_type :
|
||||
&draw_engine_gpencil_type);
|
||||
use_drw_engine(&draw_engine_gpencil_type);
|
||||
}
|
||||
if (use_basic) {
|
||||
drw_engines_enable_basic();
|
||||
|
@ -3050,7 +3038,7 @@ void DRW_engines_register()
|
|||
RE_engines_register(&DRW_engine_viewport_workbench_type);
|
||||
|
||||
DRW_engine_register(&draw_engine_gpencil_type);
|
||||
DRW_engine_register(&draw_engine_gpencil_next_type);
|
||||
// DRW_engine_register(&draw_engine_gpencil_next_type);
|
||||
|
||||
DRW_engine_register(&draw_engine_overlay_type);
|
||||
DRW_engine_register(&draw_engine_overlay_next_type);
|
||||
|
|
Loading…
Reference in New Issue