WIP: GPv3: Switch back to the GPv2 render engine #118663

Closed
Falk David wants to merge 7 commits from filedescriptor:gpv3-roll-back-renderer into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 442 additions and 44 deletions

View File

@ -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;
}
/** \} */

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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 (&deg_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);