GPv3: Render to Image
This PR refactors parts of the gpv3 engine and implements the `render_to_image` engine callback. Pull Request: https://projects.blender.org/blender/blender/pulls/115904
This commit is contained in:
@@ -44,7 +44,6 @@ class AntiAliasing {
|
|||||||
Framebuffer blend_weight_fb_ = {"blend_weight_fb"};
|
Framebuffer blend_weight_fb_ = {"blend_weight_fb"};
|
||||||
PassSimple blend_weight_ps_ = {"blend_weight_ps"};
|
PassSimple blend_weight_ps_ = {"blend_weight_ps"};
|
||||||
|
|
||||||
Framebuffer output_fb_ = {"output_fb"};
|
|
||||||
PassSimple resolve_ps_ = {"resolve_ps"};
|
PassSimple resolve_ps_ = {"resolve_ps"};
|
||||||
|
|
||||||
bool draw_wireframe_ = false;
|
bool draw_wireframe_ = false;
|
||||||
@@ -71,7 +70,7 @@ class AntiAliasing {
|
|||||||
anti_aliasing_enabled_ = true; // GPENCIL_SIMPLIFY_AA(scene);
|
anti_aliasing_enabled_ = true; // GPENCIL_SIMPLIFY_AA(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_sync(TextureFromPool &color_tx, TextureFromPool &reveal_tx)
|
void begin_sync(TextureFromPool &color_tx, Framebuffer &scene_fb, TextureFromPool &reveal_tx)
|
||||||
{
|
{
|
||||||
/* TODO(fclem): No global access. */
|
/* TODO(fclem): No global access. */
|
||||||
const float *size = DRW_viewport_size_get();
|
const float *size = DRW_viewport_size_get();
|
||||||
@@ -83,7 +82,7 @@ class AntiAliasing {
|
|||||||
/* Resolve pass. */
|
/* Resolve pass. */
|
||||||
PassSimple &pass = resolve_ps_;
|
PassSimple &pass = resolve_ps_;
|
||||||
pass.init();
|
pass.init();
|
||||||
pass.framebuffer_set(&output_fb_);
|
pass.framebuffer_set(&scene_fb);
|
||||||
pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
|
pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM);
|
||||||
pass.shader_set(shaders_.static_shader_get(ANTIALIASING_RESOLVE));
|
pass.shader_set(shaders_.static_shader_get(ANTIALIASING_RESOLVE));
|
||||||
/** \note use color_tx as dummy if AA is disabled. */
|
/** \note use color_tx as dummy if AA is disabled. */
|
||||||
@@ -96,24 +95,21 @@ class AntiAliasing {
|
|||||||
pass.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
pass.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Manager &manager, GPUTexture *dst_color_tx)
|
void draw(Manager &manager, const int2 render_resolution)
|
||||||
{
|
{
|
||||||
int2 render_size = {GPU_texture_width(dst_color_tx), GPU_texture_height(dst_color_tx)};
|
|
||||||
|
|
||||||
DRW_stats_group_start("Anti-Aliasing");
|
DRW_stats_group_start("Anti-Aliasing");
|
||||||
|
|
||||||
if (anti_aliasing_enabled_) {
|
if (anti_aliasing_enabled_) {
|
||||||
edge_detect_tx_.acquire(render_size, GPU_RG8);
|
edge_detect_tx_.acquire(render_resolution, GPU_RG8);
|
||||||
edge_detect_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(edge_detect_tx_));
|
edge_detect_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(edge_detect_tx_));
|
||||||
manager.submit(edge_detect_ps_);
|
manager.submit(edge_detect_ps_);
|
||||||
|
|
||||||
blend_weight_tx_.acquire(render_size, GPU_RGBA8);
|
blend_weight_tx_.acquire(render_resolution, GPU_RGBA8);
|
||||||
blend_weight_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(blend_weight_tx_));
|
blend_weight_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(blend_weight_tx_));
|
||||||
manager.submit(blend_weight_ps_);
|
manager.submit(blend_weight_ps_);
|
||||||
edge_detect_tx_.release();
|
edge_detect_tx_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
output_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dst_color_tx));
|
|
||||||
manager.submit(resolve_ps_);
|
manager.submit(resolve_ps_);
|
||||||
blend_weight_tx_.release();
|
blend_weight_tx_.release();
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BKE_gpencil_modifier_legacy.h"
|
#include "BKE_gpencil_modifier_legacy.h"
|
||||||
|
|
||||||
#include "BLI_listbase_wrapper.hh"
|
#include "BLI_listbase_wrapper.hh"
|
||||||
|
|
||||||
#include "DEG_depsgraph_query.hh"
|
#include "DEG_depsgraph_query.hh"
|
||||||
|
|
||||||
#include "DNA_shader_fx_types.h"
|
#include "DNA_shader_fx_types.h"
|
||||||
|
|
||||||
#include "DRW_engine.h"
|
#include "DRW_engine.h"
|
||||||
#include "DRW_render.h"
|
#include "DRW_render.h"
|
||||||
|
|
||||||
#include "ED_screen.hh"
|
#include "ED_screen.hh"
|
||||||
#include "ED_view3d.hh"
|
#include "ED_view3d.hh"
|
||||||
|
|
||||||
#include "GPU_capabilities.h"
|
#include "GPU_capabilities.h"
|
||||||
|
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
|
#include "RE_pipeline.h"
|
||||||
|
|
||||||
#include "draw_manager.hh"
|
#include "draw_manager.hh"
|
||||||
#include "draw_pass.hh"
|
#include "draw_pass.hh"
|
||||||
|
|
||||||
@@ -55,6 +64,10 @@ class Instance {
|
|||||||
TextureFromPool reveal_tx_ = {"gp_reveal_tx"};
|
TextureFromPool reveal_tx_ = {"gp_reveal_tx"};
|
||||||
Framebuffer main_fb_ = {"gp_main_fb"};
|
Framebuffer main_fb_ = {"gp_main_fb"};
|
||||||
|
|
||||||
|
/** Underlying scene pixel. Used to composite the output of the grease pencil render onto the
|
||||||
|
* scene (including merging the depth buffers). */
|
||||||
|
Framebuffer scene_fb_ = {"gp_scene_fb"};
|
||||||
|
|
||||||
/** Texture format for all intermediate buffers. */
|
/** Texture format for all intermediate buffers. */
|
||||||
eGPUTextureFormat texture_format_ = GPU_RGBA16F;
|
eGPUTextureFormat texture_format_ = GPU_RGBA16F;
|
||||||
|
|
||||||
@@ -76,6 +89,8 @@ class Instance {
|
|||||||
/** Context. */
|
/** Context. */
|
||||||
Depsgraph *depsgraph_ = nullptr;
|
Depsgraph *depsgraph_ = nullptr;
|
||||||
Object *camera_ = nullptr;
|
Object *camera_ = nullptr;
|
||||||
|
Manager *manager_ = nullptr;
|
||||||
|
draw::View view_ = {"MainView"};
|
||||||
|
|
||||||
/** \note Needs not to be temporary variable since it is dereferenced later. */
|
/** \note Needs not to be temporary variable since it is dereferenced later. */
|
||||||
std::array<float4, 2> clear_colors_ = {float4(0.0f, 0.0f, 0.0f, 0.0f),
|
std::array<float4, 2> clear_colors_ = {float4(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
@@ -88,9 +103,18 @@ class Instance {
|
|||||||
vfx(shaders),
|
vfx(shaders),
|
||||||
anti_aliasing(shaders){};
|
anti_aliasing(shaders){};
|
||||||
|
|
||||||
void init(Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d)
|
void init(Depsgraph *depsgraph,
|
||||||
|
Manager *manager,
|
||||||
|
const DRWView *viewport_draw_view,
|
||||||
|
const View3D *v3d,
|
||||||
|
const RegionView3D *rv3d)
|
||||||
{
|
{
|
||||||
depsgraph_ = depsgraph;
|
depsgraph_ = depsgraph;
|
||||||
|
manager_ = manager;
|
||||||
|
if (viewport_draw_view != nullptr) {
|
||||||
|
view_.sync(viewport_draw_view);
|
||||||
|
}
|
||||||
|
|
||||||
const Scene *scene = DEG_get_evaluated_scene(depsgraph_);
|
const Scene *scene = DEG_get_evaluated_scene(depsgraph_);
|
||||||
|
|
||||||
const bool is_viewport = (v3d != nullptr);
|
const bool is_viewport = (v3d != nullptr);
|
||||||
@@ -108,12 +132,9 @@ class Instance {
|
|||||||
anti_aliasing.init(v3d, scene);
|
anti_aliasing.init(v3d, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
void begin_sync(Manager & /*manager*/)
|
void begin_sync()
|
||||||
{
|
{
|
||||||
/* TODO(fclem): Remove global draw manager access. */
|
objects.begin_sync(depsgraph_, view_);
|
||||||
View main_view("GPencil_MainView", DRW_view_default_get());
|
|
||||||
|
|
||||||
objects.begin_sync(depsgraph_, main_view);
|
|
||||||
layers.begin_sync();
|
layers.begin_sync();
|
||||||
materials.begin_sync();
|
materials.begin_sync();
|
||||||
lights.begin_sync(depsgraph_);
|
lights.begin_sync(depsgraph_);
|
||||||
@@ -133,14 +154,15 @@ class Instance {
|
|||||||
materials.bind_resources(sub);
|
materials.bind_resources(sub);
|
||||||
lights.bind_resources(sub);
|
lights.bind_resources(sub);
|
||||||
|
|
||||||
anti_aliasing.begin_sync(color_tx_, reveal_tx_);
|
anti_aliasing.begin_sync(color_tx_, scene_fb_, reveal_tx_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void object_sync(Manager &manager, ObjectRef &object_ref)
|
void object_sync(ObjectRef &object_ref)
|
||||||
{
|
{
|
||||||
switch (object_ref.object->type) {
|
switch (object_ref.object->type) {
|
||||||
case OB_GREASE_PENCIL:
|
case OB_GREASE_PENCIL:
|
||||||
objects.sync_grease_pencil(manager, object_ref, main_fb_, depth_tx_, main_ps_);
|
objects.sync_grease_pencil(
|
||||||
|
*manager_, object_ref, main_fb_, scene_fb_, depth_tx_, main_ps_);
|
||||||
break;
|
break;
|
||||||
case OB_LAMP:
|
case OB_LAMP:
|
||||||
lights.sync(object_ref);
|
lights.sync(object_ref);
|
||||||
@@ -150,7 +172,7 @@ class Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_sync(Manager & /*manager*/)
|
void end_sync()
|
||||||
{
|
{
|
||||||
objects.end_sync();
|
objects.end_sync();
|
||||||
layers.end_sync();
|
layers.end_sync();
|
||||||
@@ -158,39 +180,68 @@ class Instance {
|
|||||||
lights.end_sync();
|
lights.end_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_viewport(Manager &manager,
|
void render_sync(RenderEngine *engine, Depsgraph *depsgraph)
|
||||||
View &view,
|
{
|
||||||
GPUTexture *dst_depth_tx,
|
/* TODO: Remove old draw manager calls. */
|
||||||
GPUTexture *dst_color_tx)
|
DRW_cache_restart();
|
||||||
|
|
||||||
|
manager_->begin_sync();
|
||||||
|
|
||||||
|
begin_sync();
|
||||||
|
|
||||||
|
auto object_sync_render =
|
||||||
|
[](void *vedata, Object *ob, RenderEngine * /*engine*/, Depsgraph * /*depsgraph*/) {
|
||||||
|
Instance &inst = *reinterpret_cast<Instance *>(vedata);
|
||||||
|
ObjectRef ob_ref = DRW_object_ref_get(ob);
|
||||||
|
inst.object_sync(ob_ref);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* HACK: We pass `this` here so we have access to the `Instance` in `object_sync_render`. */
|
||||||
|
DRW_render_object_iter(this, engine, depsgraph, object_sync_render);
|
||||||
|
|
||||||
|
end_sync();
|
||||||
|
|
||||||
|
manager_->end_sync();
|
||||||
|
|
||||||
|
/* TODO: Remove old draw manager calls. */
|
||||||
|
DRW_render_instance_buffer_finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(GPUTexture *dst_color_tx, GPUTexture *dst_depth_tx, const int2 render_resolution)
|
||||||
{
|
{
|
||||||
if (!objects.scene_has_visible_gpencil_object()) {
|
if (!objects.scene_has_visible_gpencil_object()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int2 render_size = {GPU_texture_width(dst_depth_tx), GPU_texture_height(dst_depth_tx)};
|
scene_fb_.ensure(GPU_ATTACHMENT_TEXTURE(dst_depth_tx), GPU_ATTACHMENT_TEXTURE(dst_color_tx));
|
||||||
|
|
||||||
depth_tx_.acquire(render_size, GPU_DEPTH24_STENCIL8);
|
depth_tx_.acquire(render_resolution, GPU_DEPTH24_STENCIL8);
|
||||||
color_tx_.acquire(render_size, texture_format_);
|
color_tx_.acquire(render_resolution, texture_format_);
|
||||||
reveal_tx_.acquire(render_size, texture_format_);
|
reveal_tx_.acquire(render_resolution, texture_format_);
|
||||||
main_fb_.ensure(GPU_ATTACHMENT_TEXTURE(depth_tx_),
|
main_fb_.ensure(GPU_ATTACHMENT_TEXTURE(depth_tx_),
|
||||||
GPU_ATTACHMENT_TEXTURE(color_tx_),
|
GPU_ATTACHMENT_TEXTURE(color_tx_),
|
||||||
GPU_ATTACHMENT_TEXTURE(reveal_tx_));
|
GPU_ATTACHMENT_TEXTURE(reveal_tx_));
|
||||||
|
|
||||||
scene_buf_.render_size = float2(render_size);
|
scene_buf_.render_size = float2(render_resolution);
|
||||||
scene_buf_.push_update();
|
scene_buf_.push_update();
|
||||||
|
|
||||||
objects.acquire_temporary_buffers(render_size, texture_format_);
|
objects.acquire_temporary_buffers(render_resolution, texture_format_);
|
||||||
|
|
||||||
manager.submit(main_ps_, view);
|
manager_->submit(main_ps_, view_);
|
||||||
|
|
||||||
objects.release_temporary_buffers();
|
objects.release_temporary_buffers();
|
||||||
|
|
||||||
anti_aliasing.draw(manager, dst_color_tx);
|
anti_aliasing.draw(*manager_, render_resolution);
|
||||||
|
|
||||||
depth_tx_.release();
|
depth_tx_.release();
|
||||||
color_tx_.release();
|
color_tx_.release();
|
||||||
reveal_tx_.release();
|
reveal_tx_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw::View &view()
|
||||||
|
{
|
||||||
|
return view_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::draw::greasepencil
|
} // namespace blender::draw::greasepencil
|
||||||
@@ -219,9 +270,12 @@ static void gpencil_engine_init(void *vedata)
|
|||||||
ved->instance = new draw::greasepencil::Instance();
|
ved->instance = new draw::greasepencil::Instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw::Manager *manager = DRW_manager_get();
|
||||||
const DRWContextState *ctx_state = DRW_context_state_get();
|
const DRWContextState *ctx_state = DRW_context_state_get();
|
||||||
|
const DRWView *default_view = DRW_view_default_get();
|
||||||
|
|
||||||
ved->instance->init(ctx_state->depsgraph, ctx_state->v3d, ctx_state->rv3d);
|
ved->instance->init(
|
||||||
|
ctx_state->depsgraph, manager, default_view, ctx_state->v3d, ctx_state->rv3d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpencil_draw_scene(void *vedata)
|
static void gpencil_draw_scene(void *vedata)
|
||||||
@@ -232,33 +286,29 @@ static void gpencil_draw_scene(void *vedata)
|
|||||||
}
|
}
|
||||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||||
const DRWView *default_view = DRW_view_default_get();
|
const DRWView *default_view = DRW_view_default_get();
|
||||||
draw::Manager *manager = DRW_manager_get();
|
const float2 viewport_size = DRW_viewport_size_get();
|
||||||
draw::View view("DefaultView", default_view);
|
ved->instance->view().sync(default_view);
|
||||||
ved->instance->draw_viewport(*manager, view, dtxl->depth, dtxl->color);
|
ved->instance->draw(dtxl->color, dtxl->depth, int2(viewport_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpencil_cache_init(void *vedata)
|
static void gpencil_cache_init(void *vedata)
|
||||||
{
|
{
|
||||||
draw::Manager *manager = DRW_manager_get();
|
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->begin_sync();
|
||||||
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->begin_sync(*manager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpencil_cache_populate(void *vedata, Object *object)
|
static void gpencil_cache_populate(void *vedata, Object *object)
|
||||||
{
|
{
|
||||||
draw::Manager *manager = DRW_manager_get();
|
|
||||||
|
|
||||||
draw::ObjectRef ref;
|
draw::ObjectRef ref;
|
||||||
ref.object = object;
|
ref.object = object;
|
||||||
ref.dupli_object = DRW_object_get_dupli(object);
|
ref.dupli_object = DRW_object_get_dupli(object);
|
||||||
ref.dupli_parent = DRW_object_get_dupli_parent(object);
|
ref.dupli_parent = DRW_object_get_dupli_parent(object);
|
||||||
|
|
||||||
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->object_sync(*manager, ref);
|
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->object_sync(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpencil_cache_finish(void *vedata)
|
static void gpencil_cache_finish(void *vedata)
|
||||||
{
|
{
|
||||||
draw::Manager *manager = DRW_manager_get();
|
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->end_sync();
|
||||||
reinterpret_cast<GPENCIL_NEXT_Data *>(vedata)->instance->end_sync(*manager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gpencil_instance_free(void *instance)
|
static void gpencil_instance_free(void *instance)
|
||||||
@@ -271,11 +321,107 @@ static void gpencil_engine_free()
|
|||||||
blender::draw::greasepencil::ShaderModule::module_free();
|
blender::draw::greasepencil::ShaderModule::module_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the color and depth textures of the render result in the render layer. */
|
||||||
|
static void get_render_result_textures(RenderEngine *engine,
|
||||||
|
RenderLayer *render_layer,
|
||||||
|
const draw::View &view,
|
||||||
|
const int2 render_resolution,
|
||||||
|
draw::Texture &r_color_tx,
|
||||||
|
draw::Texture &r_depth_tx)
|
||||||
|
{
|
||||||
|
/* Create depth texture & color texture from render result. */
|
||||||
|
const char *viewname = RE_GetActiveRenderView(engine->re);
|
||||||
|
RenderPass *rpass_z_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_Z, viewname);
|
||||||
|
RenderPass *rpass_col_src = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
|
||||||
|
|
||||||
|
float *pix_z = (rpass_z_src) ? rpass_z_src->ibuf->float_buffer.data : nullptr;
|
||||||
|
float *pix_col = (rpass_col_src) ? rpass_col_src->ibuf->float_buffer.data : nullptr;
|
||||||
|
|
||||||
|
if (!pix_z || !pix_col) {
|
||||||
|
RE_engine_set_error_message(engine,
|
||||||
|
"Warning: To render grease pencil, enable Combined and Z passes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pix_z) {
|
||||||
|
/* Depth need to be remapped to [0..1] range. */
|
||||||
|
pix_z = static_cast<float *>(MEM_dupallocN(pix_z));
|
||||||
|
|
||||||
|
int pix_num = rpass_z_src->rectx * rpass_z_src->recty;
|
||||||
|
|
||||||
|
if (view.is_persp()) {
|
||||||
|
for (int i = 0; i < pix_num; i++) {
|
||||||
|
pix_z[i] = (-view.winmat()[3][2] / -pix_z[i]) - view.winmat()[2][2];
|
||||||
|
pix_z[i] = clamp_f(pix_z[i] * 0.5f + 0.5f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Keep in mind, near and far distance are negatives. */
|
||||||
|
float near = view.near_clip();
|
||||||
|
float far = view.far_clip();
|
||||||
|
float range_inv = 1.0f / fabsf(far - near);
|
||||||
|
for (int i = 0; i < pix_num; i++) {
|
||||||
|
pix_z[i] = (pix_z[i] + near) * range_inv;
|
||||||
|
pix_z[i] = clamp_f(pix_z[i], 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME(fclem): we have a precision loss in the depth buffer because of this re-upload.
|
||||||
|
* Find where it comes from! */
|
||||||
|
const eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ;
|
||||||
|
r_depth_tx.ensure_2d(GPU_DEPTH_COMPONENT24, render_resolution, usage, pix_z);
|
||||||
|
r_color_tx.ensure_2d(GPU_RGBA16F, render_resolution, usage, pix_col);
|
||||||
|
}
|
||||||
|
|
||||||
static void gpencil_render_to_image(void * /*vedata*/,
|
static void gpencil_render_to_image(void * /*vedata*/,
|
||||||
RenderEngine * /*engine*/,
|
RenderEngine *engine,
|
||||||
RenderLayer * /*layer*/,
|
RenderLayer *render_layer,
|
||||||
const rcti * /*rect*/)
|
const rcti * /*rect*/)
|
||||||
{
|
{
|
||||||
|
draw::greasepencil::Instance instance;
|
||||||
|
draw::Manager &manager = *DRW_manager_get();
|
||||||
|
|
||||||
|
Render *render = engine->re;
|
||||||
|
Depsgraph *depsgraph = DRW_context_state_get()->depsgraph;
|
||||||
|
Scene *scene = DRW_context_state_get()->scene;
|
||||||
|
Object *camera_original_ob = RE_GetCamera(render);
|
||||||
|
const char *viewname = RE_GetActiveRenderView(render);
|
||||||
|
const int2 render_resolution = int2(engine->resolution_x, engine->resolution_y);
|
||||||
|
|
||||||
|
instance.init(depsgraph, &manager, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
|
float4x4 viewinv, winmat;
|
||||||
|
Object *camera_eval = DEG_get_evaluated_object(depsgraph, camera_original_ob);
|
||||||
|
RE_GetCameraModelMatrix(render, camera_eval, viewinv.ptr());
|
||||||
|
float4x4 viewmat = math::invert(viewinv);
|
||||||
|
RE_GetCameraWindow(render, camera_eval, winmat.ptr());
|
||||||
|
|
||||||
|
instance.view().sync(viewmat, winmat);
|
||||||
|
instance.render_sync(engine, depsgraph);
|
||||||
|
|
||||||
|
draw::Texture color_tx;
|
||||||
|
draw::Texture depth_tx;
|
||||||
|
/* TODO: Support `R_BORDER` render mode. */
|
||||||
|
get_render_result_textures(
|
||||||
|
engine, render_layer, instance.view(), render_resolution, color_tx, depth_tx);
|
||||||
|
|
||||||
|
instance.draw(color_tx, depth_tx, render_resolution);
|
||||||
|
|
||||||
|
RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
|
||||||
|
if (!rp) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float *result = reinterpret_cast<float *>(color_tx.read<float4>(GPU_DATA_FLOAT));
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
BLI_mutex_lock(&engine->update_render_passes_mutex);
|
||||||
|
/* WORKAROUND: We use texture read to avoid using a frame-buffer to get the render result.
|
||||||
|
* However, on some implementation, we need a buffer with a few extra bytes for the read to
|
||||||
|
* happen correctly (see #GLTexture::read()). So we need a custom memory allocation. */
|
||||||
|
/* Avoid `memcpy()`, replace the pointer directly. */
|
||||||
|
RE_pass_set_buffer_data(rp, result);
|
||||||
|
BLI_mutex_unlock(&engine->update_render_passes_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ class ObjectModule {
|
|||||||
void sync_grease_pencil(Manager &manager,
|
void sync_grease_pencil(Manager &manager,
|
||||||
ObjectRef &object_ref,
|
ObjectRef &object_ref,
|
||||||
Framebuffer &main_fb,
|
Framebuffer &main_fb,
|
||||||
|
Framebuffer &scene_fb,
|
||||||
TextureFromPool &depth_tx,
|
TextureFromPool &depth_tx,
|
||||||
PassSortable &main_ps)
|
PassSortable &main_ps)
|
||||||
{
|
{
|
||||||
@@ -196,9 +197,10 @@ class ObjectModule {
|
|||||||
object_subpass.draw(geom, handle);
|
object_subpass.draw(geom, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Merging the object depth buffer into the scene depth buffer. */
|
||||||
float4x4 plane_mat = get_object_plane_mat(*object);
|
float4x4 plane_mat = get_object_plane_mat(*object);
|
||||||
ResourceHandle handle_plane_mat = manager.resource_handle(plane_mat);
|
ResourceHandle handle_plane_mat = manager.resource_handle(plane_mat);
|
||||||
object_subpass.framebuffer_set(&DRW_viewport_framebuffer_list_get()->depth_only_fb);
|
object_subpass.framebuffer_set(&scene_fb);
|
||||||
object_subpass.state_set(DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH);
|
object_subpass.state_set(DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_DEPTH);
|
||||||
object_subpass.shader_set(shaders_.static_shader_get(DEPTH_MERGE));
|
object_subpass.shader_set(shaders_.static_shader_get(DEPTH_MERGE));
|
||||||
object_subpass.bind_texture("depthBuf", (object_has_vfx) ? nullptr : &depth_tx);
|
object_subpass.bind_texture("depthBuf", (object_has_vfx) ? nullptr : &depth_tx);
|
||||||
|
|||||||
Reference in New Issue
Block a user