GPv3: Python API for frame, drawing and drawing attributes #124787

Merged
Falk David merged 22 commits from filedescriptor/blender:gpv3-drawing-python-api into main 2024-07-26 16:30:21 +02:00
12 changed files with 85 additions and 45 deletions
Showing only changes of commit 792cfb3be1 - Show all commits

View File

@ -470,6 +470,7 @@ void Film::sync()
cryptomatte_post_ps_.shader_set(inst_.shaders.static_shader_get(FILM_CRYPTOMATTE_POST));
cryptomatte_post_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_);
cryptomatte_post_ps_.bind_image("weight_img", &weight_tx_.current());
cryptomatte_post_ps_.bind_resources(inst_.uniform_data);
cryptomatte_post_ps_.push_constant("cryptomatte_layer_len", cryptomatte_layer_count);
cryptomatte_post_ps_.push_constant("cryptomatte_samples_per_layer",
inst_.view_layer->cryptomatte_levels);

View File

@ -59,7 +59,7 @@ GPU_SHADER_CREATE_INFO(eevee_film_cryptomatte_post)
.push_constant(Type::INT, "cryptomatte_samples_per_layer")
.local_group_size(FILM_GROUP_SIZE, FILM_GROUP_SIZE)
.compute_source("eevee_film_cryptomatte_post_comp.glsl")
.additional_info("eevee_shared");
.additional_info("eevee_global_ubo", "eevee_shared");
GPU_SHADER_CREATE_INFO(eevee_film_copy_frag)
.do_static_compilation(true)

View File

@ -253,14 +253,6 @@ static ARegion *hud_region_add(ScrArea *area)
region->overlap = true;
region->flag |= RGN_FLAG_DYNAMIC_SIZE;
if (region_win) {
float x, y;
UI_view2d_scroller_size_get(&region_win->v2d, true, &x, &y);
region->runtime.offset_x = x;
region->runtime.offset_y = y;
}
return region;
}
@ -356,6 +348,16 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
ED_region_floating_init(region);
ED_region_tag_redraw(region);
/* We need to update/initialize the runtime offsets. */
ARegion *region_win = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
if (region_win) {
float x, y;
UI_view2d_scroller_size_get(&region_win->v2d, true, &x, &y);
region->runtime.offset_x = x;
region->runtime.offset_y = y;
}
/* Reset zoom level (not well supported). */
rctf reset_rect = {};
reset_rect.xmax = region->winx;

View File

@ -1425,7 +1425,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
/* Linking non-grease-pencil materials to a grease-pencil object causes issues.
* We make sure that if one of the objects is a grease-pencil object, the other must be
* as well. */
((ob_src->type == OB_GPENCIL_LEGACY) == (ob_dst->type == OB_GPENCIL_LEGACY)))
((ob_src->type == OB_GREASE_PENCIL) == (ob_dst->type == OB_GREASE_PENCIL)))
{
return true;
}
@ -1450,7 +1450,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst
}
break;
case MAKE_LINKS_SHADERFX:
if ((ob_src->type == OB_GPENCIL_LEGACY) && (ob_dst->type == OB_GPENCIL_LEGACY)) {
if ((ob_src->type == OB_GREASE_PENCIL) && (ob_dst->type == OB_GREASE_PENCIL)) {
return true;
}
break;

View File

@ -13,7 +13,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_legacy_types.h"
#include "DNA_grease_pencil_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_shader_fx_types.h"
@ -85,8 +85,9 @@ ShaderFxData *shaderfx_add(
/* make sure effect data has unique name */
BKE_shaderfx_unique_name(&ob->shader_fx, new_fx);
bGPdata *gpd = static_cast<bGPdata *>(ob->data);
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
BLI_assert(ob->type == OB_GREASE_PENCIL);
GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(bmain);

View File

@ -377,7 +377,7 @@ static void draw_seq_in_view(bContext *C, wmWindow * /*win*/, wmDrag *drag, cons
float strip_len = update_overlay_strip_position_data(C, mval);
GPU_matrix_push();
UI_view2d_view_ortho(&region->v2d);
wmOrtho2_region_pixelspace(region);
/* Sometimes the active theme is not the sequencer theme, e.g. when an operator invokes the
* file browser. This makes sure we get the right color values for the theme. */
@ -401,7 +401,7 @@ static void draw_seq_in_view(bContext *C, wmWindow * /*win*/, wmDrag *drag, cons
float pixelx = BLI_rctf_size_x(&region->v2d.cur) / BLI_rcti_size_x(&region->v2d.mask);
float pixely = BLI_rctf_size_y(&region->v2d.cur) / BLI_rcti_size_y(&region->v2d.mask);
StripsDrawBatch batch(pixelx, pixely);
StripsDrawBatch batch(&region->v2d);
for (int i = 0; i < coords->channel_len; i++) {
float y1 = floorf(coords->channel) + i + SEQ_STRIP_OFSBOTTOM;

View File

@ -8,7 +8,10 @@
#include "sequencer_strips_batch.hh"
#include "BLI_rect.h"
#include "DNA_userdef_types.h"
#include "DNA_view2d_types.h"
#include "GPU_batch.hh"
#include "GPU_batch_presets.hh"
@ -39,12 +42,15 @@ float calc_strip_round_radius(float pixely)
return 8.0f;
}
StripsDrawBatch::StripsDrawBatch(float pixelx, float pixely) : strips_(GPU_SEQ_STRIP_DRAW_DATA_LEN)
StripsDrawBatch::StripsDrawBatch(const View2D *v2d) : strips_(GPU_SEQ_STRIP_DRAW_DATA_LEN)
{
context_.pixelx = pixelx;
context_.pixely = pixely;
context_.inv_pixelx = 1.0f / pixelx;
context_.inv_pixely = 1.0f / pixely;
view_mask_min_ = float2(v2d->mask.xmin, v2d->mask.ymin);
view_mask_size_ = float2(BLI_rcti_size_x(&v2d->mask), BLI_rcti_size_y(&v2d->mask));
view_cur_min_ = float2(v2d->cur.xmin, v2d->cur.ymin);
float2 view_cur_size = float2(BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur));
view_cur_inv_size_ = 1.0f / view_cur_size;
float pixely = view_cur_size.y / view_mask_size_.y;
context_.round_radius = calc_strip_round_radius(pixely);
context_.pixelsize = U.pixelsize;
@ -91,14 +97,14 @@ SeqStripDrawData &StripsDrawBatch::add_strip(float content_start,
strips_count_++;
memset(&res, 0, sizeof(res));
res.content_start = content_start;
res.content_end = content_end;
res.top = top;
res.bottom = bottom;
res.strip_content_top = content_top;
res.left_handle = left_handle;
res.right_handle = right_handle;
res.handle_width = handle_width;
res.content_start = pos_to_pixel_space_x(content_start);
res.content_end = pos_to_pixel_space_x(content_end);
res.top = pos_to_pixel_space_y(top);
res.bottom = pos_to_pixel_space_y(bottom);
res.strip_content_top = pos_to_pixel_space_y(content_top);
res.left_handle = pos_to_pixel_space_x(left_handle);
res.right_handle = pos_to_pixel_space_x(right_handle);
res.handle_width = size_to_pixel_space_x(handle_width);
if (single_image) {
res.flags |= GPU_SEQ_FLAG_SINGLE_IMAGE;
}

View File

@ -9,10 +9,12 @@
#pragma once
#include "BLI_array.hh"
#include "BLI_math_vector_types.hh"
#include "GPU_shader_shared.hh"
struct GPUShader;
struct GPUUniformBuf;
struct View2D;
namespace blender::gpu {
class Batch;
@ -20,6 +22,11 @@ class Batch;
namespace blender::ed::seq {
/* Utility to draw VSE timeline strip widgets in batches, with a dedicated
* shader. Internally, strip data for drawing is encoded into a uniform
* buffer. Strip coordinates are converted into pixel space, to avoid
* precision issues at large frames. Drawing assumes that a pixel space
* projection matrix is set. */
class StripsDrawBatch {
SeqContextDrawData context_;
Array<SeqStripDrawData> strips_;
@ -31,8 +38,13 @@ class StripsDrawBatch {
int binding_strips_ = 0;
int strips_count_ = 0;
float2 view_mask_min_;
float2 view_mask_size_;
float2 view_cur_min_;
float2 view_cur_inv_size_;
public:
StripsDrawBatch(float pixelx, float pixely);
StripsDrawBatch(const View2D *v2d);
~StripsDrawBatch();
SeqStripDrawData &add_strip(float content_start,
@ -46,6 +58,22 @@ class StripsDrawBatch {
bool single_image);
void flush_batch();
private:
/* Same math as `UI_view2d_view_to_region_*` but avoiding divisions,
* and without relying on View2D data type. */
inline float pos_to_pixel_space_x(float x) const
{
return (view_mask_min_.x + (x - view_cur_min_.x) * view_cur_inv_size_.x) * view_mask_size_.x;
}
inline float pos_to_pixel_space_y(float y) const
{
return (view_mask_min_.y + (y - view_cur_min_.y) * view_cur_inv_size_.y) * view_mask_size_.y;
}
inline float size_to_pixel_space_x(float x) const
{
return x * view_cur_inv_size_.x * view_mask_size_.x;
}
};
uint color_pack(const uchar rgba[4]);

View File

@ -1253,6 +1253,9 @@ static void draw_strips_background(TimelineDrawContext *timeline_ctx,
StripsDrawBatch &strips_batch,
const Vector<StripDrawContext> &strips)
{
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(timeline_ctx->region);
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
const bool show_overlay = (timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) != 0;
@ -1322,6 +1325,7 @@ static void draw_strips_background(TimelineDrawContext *timeline_ctx,
}
strips_batch.flush_batch();
GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_pop_projection();
}
static void strip_data_missing_media_flags_set(const StripDrawContext &strip,
@ -1449,6 +1453,8 @@ static void draw_strips_foreground(TimelineDrawContext *timeline_ctx,
StripsDrawBatch &strips_batch,
const Vector<StripDrawContext> &strips)
{
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(timeline_ctx->region);
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
for (const StripDrawContext &strip : strips) {
@ -1471,6 +1477,7 @@ static void draw_strips_foreground(TimelineDrawContext *timeline_ctx,
strips_batch.flush_batch();
GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_pop_projection();
}
static void draw_retiming_continuity_ranges(TimelineDrawContext *timeline_ctx,
@ -1908,7 +1915,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
{
SeqQuadsBatch quads_batch;
TimelineDrawContext ctx = timeline_draw_context_get(C, &quads_batch);
StripsDrawBatch strips_batch(ctx.pixelx, ctx.pixely);
StripsDrawBatch strips_batch(ctx.v2d);
draw_timeline_pre_view_callbacks(&ctx);
UI_ThemeClearColor(TH_BACK);

View File

@ -140,8 +140,6 @@ BLI_STATIC_ASSERT(sizeof(SeqStripDrawData) * GPU_SEQ_STRIP_DRAW_DATA_LEN <= 1638
/* VSE global data for timeline rendering. */
struct SeqContextDrawData {
float pixelx, pixely; /* Size of one pixel in timeline coordinate space. */
float inv_pixelx, inv_pixely;
float round_radius;
float pixelsize;
uint col_back;

View File

@ -44,18 +44,15 @@ void main()
SeqStripDrawData strip = strip_data[strip_id];
/* Transform strip rectangle into pixel coordinates, so that
* rounded corners have proper aspect ratio and can be expressed in pixels.
* Also snap to pixel grid coordinates, so that outline/border is clear
* non-fractional pixel sizes. */
vec2 view_to_pixel = vec2(context_data.inv_pixelx, context_data.inv_pixely);
vec2 pos1 = round(vec2(strip.left_handle, strip.bottom) * view_to_pixel);
vec2 pos2 = round(vec2(strip.right_handle, strip.top) * view_to_pixel);
/* Snap to pixel grid coordinates, so that outline/border is non-fractional
* pixel sizes. */
vec2 pos1 = round(vec2(strip.left_handle, strip.bottom));
vec2 pos2 = round(vec2(strip.right_handle, strip.top));
/* Make sure strip is at least 1px wide. */
pos2.x = max(pos2.x, pos1.x + 1.0);
vec2 size = (pos2 - pos1) * 0.5;
vec2 center = (pos1 + pos2) * 0.5;
vec2 pos = round(co * view_to_pixel);
vec2 pos = round(co);
float radius = context_data.round_radius;
if (radius > size.x) {
@ -72,7 +69,7 @@ void main()
/* Distance to inner part when handles are taken into account. */
float sdf_inner = sdf;
if ((strip.flags & GPU_SEQ_FLAG_ANY_HANDLE) != 0) {
float handle_width = strip.handle_width * view_to_pixel.x;
float handle_width = strip.handle_width;
/* Take left/right handle from horizontal sides. */
if ((strip.flags & GPU_SEQ_FLAG_DRAW_LH) != 0) {
pos1.x += handle_width;
@ -107,7 +104,7 @@ void main()
if (co.y < strip.strip_content_top) {
col.rgb = unpackUnorm4x8(strip.col_color_band).rgb;
/* Darker line to better separate the color band. */
if (co.y > strip.strip_content_top - context_data.pixely) {
if (co.y > strip.strip_content_top - 1.0) {
col.rgb = color_shade(col.rgb, -20.0);
}
}

View File

@ -9,8 +9,8 @@ void main()
int vid = gl_VertexID;
SeqStripDrawData strip = strip_data[id];
vec4 rect = vec4(strip.left_handle, strip.bottom, strip.right_handle, strip.top);
/* Expand by 2px to fit possible pixel grid rounding. */
vec2 expand = vec2(context_data.pixelx, context_data.pixely);
/* Expand by 1px to fit pixel grid rounding. */
vec2 expand = vec2(1.0, 1.0);
rect.xy -= expand;
rect.zw += expand;