Blender V4.5
workbench_engine.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_rect.h"
6
7#include "DNA_fluid_types.h"
8
9#include "BKE_editmesh.hh"
10#include "BKE_material.hh"
11#include "BKE_modifier.hh"
12#include "BKE_object.hh"
13#include "BKE_paint.hh"
14#include "BKE_paint_bvh.hh"
15#include "BKE_particle.h"
16
18
20#include "ED_paint.hh"
21#include "ED_view3d.hh"
22
23#include "BLT_translation.hh"
24
25#include "GPU_context.hh"
26#include "IMB_imbuf_types.hh"
27
28#include "RE_engine.h"
29#include "RE_pipeline.h"
30
31#include "draw_cache.hh"
32#include "draw_common.hh"
33#include "draw_sculpt.hh"
34#include "draw_view_data.hh"
35
36#include "workbench_private.hh"
37
38#include "workbench_engine.h" /* Own include. */
39
40namespace blender::workbench {
41
42using namespace draw;
43
44class Instance : public DrawEngine {
45 private:
46 View view_ = {"DefaultView"};
47
48 SceneState scene_state_;
49
50 SceneResources resources_;
51
52 OpaquePass opaque_ps_;
53 TransparentPass transparent_ps_;
54 TransparentDepthPass transparent_depth_ps_;
55
56 ShadowPass shadow_ps_;
57 VolumePass volume_ps_;
58 OutlinePass outline_ps_;
59 DofPass dof_ps_;
60 AntiAliasingPass anti_aliasing_ps_;
61
62 /* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get.
63 * They never get actually used. */
64 Vector<GPUMaterial *> dummy_gpu_materials_ = {1, nullptr, {}};
65
66 /* Used to detect any scene data update. */
67 uint64_t depsgraph_last_update_ = 0;
68
69 public:
70 const DRWContext *draw_ctx = nullptr;
71
73 {
74 return "Workbench";
75 }
76
78 {
79 if (material_count > dummy_gpu_materials_.size()) {
80 dummy_gpu_materials_.resize(material_count, nullptr);
81 }
82 return dummy_gpu_materials_.as_span().slice(IndexRange(material_count));
83 };
84
85 void init() final
86 {
87 this->draw_ctx = DRW_context_get();
88 init(draw_ctx->depsgraph);
89 }
90
91 void init(Depsgraph *depsgraph, Object *camera_ob = nullptr)
92 {
93 this->draw_ctx = DRW_context_get();
94 bool scene_updated = assign_if_different(depsgraph_last_update_,
96
97 scene_state_.init(this->draw_ctx, scene_updated, camera_ob);
98 shadow_ps_.init(scene_state_, resources_);
99 resources_.init(scene_state_, this->draw_ctx);
100
101 outline_ps_.init(scene_state_);
102 dof_ps_.init(scene_state_, this->draw_ctx);
103 anti_aliasing_ps_.init(scene_state_);
104 }
105
107 {
108 resources_.material_buf.clear_and_trim();
109
110 opaque_ps_.sync(scene_state_, resources_);
111 transparent_ps_.sync(scene_state_, resources_);
112 transparent_depth_ps_.sync(scene_state_, resources_);
113
114 shadow_ps_.sync();
115 volume_ps_.sync(resources_);
116 outline_ps_.sync(resources_);
117 dof_ps_.sync(resources_, this->draw_ctx);
118 anti_aliasing_ps_.sync(scene_state_, resources_);
119 }
120
122 {
123 resources_.material_buf.push_update();
124 }
125
126 Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot = 0)
127 {
128 switch (color_type) {
130 return Material(*ob_ref.object);
132 return Material(*ob_ref.object, true);
134 return scene_state_.material_override;
136 return scene_state_.material_attribute_color;
140 if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, slot + 1)) {
141 return Material(*_mat);
142 }
144 default:
146 }
147 }
148
149 void object_sync(ObjectRef &ob_ref, Manager &manager) final
150 {
151 if (scene_state_.render_finished) {
152 return;
153 }
154
155 Object *ob = ob_ref.object;
156 if (!DRW_object_is_renderable(ob)) {
157 return;
158 }
159
160 const ObjectState object_state = ObjectState(this->draw_ctx, scene_state_, resources_, ob);
161
162 bool is_object_data_visible = (DRW_object_visibility_in_active_context(ob) &
164 (ob->dt >= OB_SOLID || draw_ctx->is_scene_render());
165
166 if (!(ob->base_flag & BASE_FROM_DUPLI)) {
168 if (md && BKE_modifier_is_enabled(scene_state_.scene, md, eModifierMode_Realtime)) {
170 if (fmd->domain) {
171 volume_ps_.object_sync_modifier(manager, resources_, scene_state_, ob_ref, md);
172
173 if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
174 /* Do not draw solid in this case. */
175 is_object_data_visible = false;
176 }
177 }
178 }
179 }
180
181 ResourceHandle emitter_handle(0);
182
183 if (is_object_data_visible) {
184 if (object_state.sculpt_pbvh) {
186 *bke::object::pbvh_get(*ob_ref.object));
187 const float3 center = math::midpoint(bounds.min, bounds.max);
188 const float3 half_extent = bounds.max - center;
189 ResourceHandle handle = manager.resource_handle(ob_ref, nullptr, &center, &half_extent);
190 this->sculpt_sync(ob_ref, handle, object_state);
191 emitter_handle = handle;
192 }
193 else if (ob->type == OB_MESH) {
194 ResourceHandle handle = manager.resource_handle(ob_ref);
195 this->mesh_sync(ob_ref, handle, object_state);
196 emitter_handle = handle;
197 }
198 else if (ob->type == OB_POINTCLOUD) {
199 this->pointcloud_sync(manager, ob_ref, object_state);
200 }
201 else if (ob->type == OB_CURVES) {
202 this->curves_sync(manager, ob_ref, object_state);
203 }
204 else if (ob->type == OB_VOLUME) {
205 if (scene_state_.shading.type != OB_WIRE) {
206 volume_ps_.object_sync_volume(manager,
207 resources_,
208 scene_state_,
209 ob_ref,
210 get_material(ob_ref, object_state.color_type).base_color);
211 }
212 }
213 }
214
215 if (ob->type == OB_MESH && ob->modifiers.first != nullptr) {
217 if (md->type != eModifierType_ParticleSystem) {
218 continue;
219 }
220 ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
222 continue;
223 }
224 ParticleSettings *part = psys->part;
225 const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
226
227 if (draw_as == PART_DRAW_PATH) {
228 this->hair_sync(manager, ob_ref, emitter_handle, object_state, psys, md);
229 }
230 }
231 }
232 }
233
234 template<typename F>
235 void draw_to_mesh_pass(ObjectRef &ob_ref, bool is_transparent, F draw_callback)
236 {
237 const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0;
238
239 if (scene_state_.xray_mode || is_transparent) {
240 if (in_front) {
241 draw_callback(transparent_ps_.accumulation_in_front_ps_);
242 draw_callback(transparent_depth_ps_.in_front_ps_);
243 }
244 else {
245 draw_callback(transparent_ps_.accumulation_ps_);
246 draw_callback(transparent_depth_ps_.main_ps_);
247 }
248 }
249 else {
250 if (in_front) {
251 draw_callback(opaque_ps_.gbuffer_in_front_ps_);
252 }
253 else {
254 draw_callback(opaque_ps_.gbuffer_ps_);
255 }
256 }
257 }
258
259 void draw_mesh(ObjectRef &ob_ref,
260 Material &material,
261 gpu::Batch *batch,
262 ResourceHandle handle,
263 const MaterialTexture *texture = nullptr,
264 bool show_missing_texture = false)
265 {
266 resources_.material_buf.append(material);
267 int material_index = resources_.material_buf.size() - 1;
268
269 if (show_missing_texture && (!texture || !texture->gpu.texture)) {
270 texture = &resources_.missing_texture;
271 }
272
273 this->draw_to_mesh_pass(ob_ref, material.is_transparent(), [&](MeshPass &mesh_pass) {
274 mesh_pass.get_subpass(eGeometryType::MESH, texture).draw(batch, handle, material_index);
275 });
276 }
277
278 void mesh_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
279 {
280 bool has_transparent_material = false;
281
282 if (object_state.use_per_material_batches) {
283 const int material_count = BKE_object_material_used_with_fallback_eval(*ob_ref.object);
284
285 Span<gpu::Batch *> batches;
286 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
288 }
289 else {
291 ob_ref.object, this->get_dummy_gpu_materials(material_count));
292 }
293
294 if (!batches.is_empty()) {
295 for (auto i : IndexRange(material_count)) {
296 if (batches[i] == nullptr) {
297 continue;
298 }
299
300 int material_slot = i;
301 Material mat = this->get_material(ob_ref, object_state.color_type, material_slot);
302 has_transparent_material = has_transparent_material || mat.is_transparent();
303
305 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
306 texture = MaterialTexture(ob_ref.object, material_slot);
307 }
308
309 this->draw_mesh(
310 ob_ref, mat, batches[i], handle, &texture, object_state.show_missing_texture);
311 }
312 }
313 }
314 else {
315 gpu::Batch *batch;
316 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
318 }
319 else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
320 if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) {
322 }
323 else {
325 }
326 }
327 else {
329 }
330
331 if (batch) {
332 Material mat = this->get_material(ob_ref, object_state.color_type);
333 has_transparent_material = has_transparent_material || mat.is_transparent();
334
335 this->draw_mesh(ob_ref, mat, batch, handle, &object_state.image_paint_override);
336 }
337 }
338
339 if (object_state.draw_shadow) {
340 shadow_ps_.object_sync(scene_state_, ob_ref, handle, has_transparent_material);
341 }
342 }
343
344 void sculpt_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
345 {
347 if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
348 features = SCULPT_BATCH_VERTEX_COLOR;
349 }
350 else if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
351 features = SCULPT_BATCH_UV;
352 }
353
354 if (object_state.use_per_material_batches) {
355 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
356 Material mat = this->get_material(ob_ref, object_state.color_type, batch.material_slot);
357 if (SCULPT_DEBUG_DRAW) {
358 mat.base_color = batch.debug_color();
359 }
360
362 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
363 texture = MaterialTexture(ob_ref.object, batch.material_slot);
364 }
365
366 this->draw_mesh(
367 ob_ref, mat, batch.batch, handle, &texture, object_state.show_missing_texture);
368 }
369 }
370 else {
371 Material mat = this->get_material(ob_ref, object_state.color_type);
372 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
373 if (SCULPT_DEBUG_DRAW) {
374 mat.base_color = batch.debug_color();
375 }
376
377 this->draw_mesh(ob_ref, mat, batch.batch, handle, &object_state.image_paint_override);
378 }
379 }
380 }
381
382 void pointcloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
383 {
384 ResourceHandle handle = manager.resource_handle(ob_ref);
385
386 Material mat = this->get_material(ob_ref, object_state.color_type);
387 resources_.material_buf.append(mat);
388 int material_index = resources_.material_buf.size() - 1;
389
390 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
391 PassMain::Sub &pass =
392 mesh_pass.get_subpass(eGeometryType::POINTCLOUD).sub("Point Cloud SubPass");
393 gpu::Batch *batch = pointcloud_sub_pass_setup(pass, ob_ref.object);
394 pass.draw(batch, handle, material_index);
395 });
396 }
397
399 ObjectRef &ob_ref,
400 ResourceHandle emitter_handle,
401 const ObjectState &object_state,
402 ParticleSystem *psys,
403 ModifierData *md)
404 {
405 /* Skip frustum culling. */
406 ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world());
407
408 Material mat = this->get_material(ob_ref, object_state.color_type, psys->part->omat - 1);
410 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
411 texture = MaterialTexture(ob_ref.object, psys->part->omat - 1);
412 }
413 resources_.material_buf.append(mat);
414 int material_index = resources_.material_buf.size() - 1;
415
416 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
417 PassMain::Sub &pass =
418 mesh_pass.get_subpass(eGeometryType::CURVES, &texture).sub("Hair SubPass");
419 pass.push_constant("emitter_object_id", int(emitter_handle.raw));
420 gpu::Batch *batch = hair_sub_pass_setup(pass, scene_state_.scene, ob_ref, psys, md);
421 pass.draw(batch, handle, material_index);
422 });
423 }
424
425 void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
426 {
427 /* Skip frustum culling. */
428 ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world());
429
430 Material mat = this->get_material(ob_ref, object_state.color_type);
431 resources_.material_buf.append(mat);
432 int material_index = resources_.material_buf.size() - 1;
433
434 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
435 PassMain::Sub &pass = mesh_pass.get_subpass(eGeometryType::CURVES).sub("Curves SubPass");
436 gpu::Batch *batch = curves_sub_pass_setup(pass, scene_state_.scene, ob_ref.object);
437 pass.draw(batch, handle, material_index);
438 });
439 }
440
442 GPUTexture *depth_tx,
443 GPUTexture *depth_in_front_tx,
444 GPUTexture *color_tx)
445 {
446 int2 resolution = scene_state_.resolution;
447
450 bool needs_depth_in_front = !transparent_ps_.accumulation_in_front_ps_.is_empty() ||
451 (!opaque_ps_.gbuffer_in_front_ps_.is_empty() &&
452 scene_state_.sample == 0);
453 resources_.depth_in_front_tx.wrap(needs_depth_in_front ? depth_in_front_tx : nullptr);
454 if (!needs_depth_in_front || opaque_ps_.gbuffer_in_front_ps_.is_empty()) {
455 resources_.clear_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_in_front_tx));
456 resources_.clear_in_front_fb.bind();
457 GPU_framebuffer_clear_depth_stencil(resources_.clear_in_front_fb, 1.0f, 0x00);
458 }
459
460 resources_.depth_tx.wrap(depth_tx);
461 resources_.color_tx.wrap(color_tx);
462
463 if (scene_state_.render_finished) {
464 /* Just copy back the already rendered result */
465 anti_aliasing_ps_.draw(
466 draw_ctx, manager, View::default_get(), scene_state_, resources_, depth_in_front_tx);
467 return;
468 }
469
470 anti_aliasing_ps_.setup_view(view_, scene_state_);
471
472 GPUAttachment id_attachment = GPU_ATTACHMENT_NONE;
473 if (scene_state_.draw_object_id) {
474 resources_.object_id_tx.acquire(
476 id_attachment = GPU_ATTACHMENT_TEXTURE(resources_.object_id_tx);
477 }
478 resources_.clear_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources_.depth_tx),
479 GPU_ATTACHMENT_TEXTURE(resources_.color_tx),
480 id_attachment);
481 resources_.clear_fb.bind();
482 float4 clear_colors[2] = {scene_state_.background_color, float4(0.0f)};
483 GPU_framebuffer_multi_clear(resources_.clear_fb, reinterpret_cast<float(*)[4]>(clear_colors));
484 GPU_framebuffer_clear_depth_stencil(resources_.clear_fb, 1.0f, 0x00);
485
486 opaque_ps_.draw(
487 manager, view_, resources_, resolution, scene_state_.draw_shadows ? &shadow_ps_ : nullptr);
488 transparent_ps_.draw(manager, view_, resources_, resolution);
489 transparent_depth_ps_.draw(manager, view_, resources_);
490
491 volume_ps_.draw(manager, view_, resources_);
492 outline_ps_.draw(manager, resources_);
493 dof_ps_.draw(manager, view_, resources_, resolution);
494 anti_aliasing_ps_.draw(draw_ctx, manager, view_, scene_state_, resources_, depth_in_front_tx);
495
496 resources_.object_id_tx.release();
497 }
498
500 GPUTexture *depth_tx,
501 GPUTexture *depth_in_front_tx,
502 GPUTexture *color_tx)
503 {
504 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
505
506 if (scene_state_.sample + 1 < scene_state_.samples_len) {
508 }
509 }
510
511 void draw(Manager &manager) final
512 {
513 DefaultTextureList *dtxl = draw_ctx->viewport_texture_list_get();
514
516 if (draw_ctx->is_viewport_image_render()) {
517 draw_image_render(manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
518 }
519 else {
520 draw_viewport(manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
521 }
523 }
524
526 GPUTexture *depth_tx,
527 GPUTexture *depth_in_front_tx,
528 GPUTexture *color_tx,
529 RenderEngine *engine = nullptr)
530 {
531 if (scene_state_.render_finished) {
532 /* This can happen in viewport animation renders, if the scene didn't have any updates
533 * between frames. */
534 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
535 return;
536 }
537
538 BLI_assert(scene_state_.sample == 0);
539 for (auto i : IndexRange(scene_state_.samples_len)) {
540 if (engine && RE_engine_test_break(engine)) {
541 break;
542 }
543 if (i != 0) {
544 scene_state_.sample = i;
545 /* Re-sync anything dependent on scene_state.sample. */
546 resources_.init(scene_state_, draw_ctx);
547 dof_ps_.init(scene_state_, draw_ctx);
548 anti_aliasing_ps_.sync(scene_state_, resources_);
549 }
550 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
551 /* Perform render step between samples to allow
552 * flushing of freed GPUBackend resources. */
554 GPU_flush();
555 }
557 }
558 }
559};
560
562{
563 return new Instance();
564}
565
567{
568 ShaderCache::release();
569}
570
571} // namespace blender::workbench
572
573/* -------------------------------------------------------------------- */
576
577using namespace blender;
578
579/* RENDER */
580
582{
583 /* For image render, allocate own buffers because we don't have a viewport. */
584 const float2 viewport_size = draw_ctx->viewport_size_get();
585 const int2 size = {int(viewport_size.x), int(viewport_size.y)};
586
588
589 /* When doing a multi view rendering the first view will allocate the buffers
590 * the other views will reuse these buffers */
591 if (dtxl->color == nullptr) {
592 BLI_assert(dtxl->depth == nullptr);
595 "txl.color", size.x, size.y, 1, GPU_RGBA16F, usage, nullptr);
597 "txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
599 "txl.depth_in_front", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
600 }
601
602 if (!(dtxl->depth && dtxl->color && dtxl->depth_in_front)) {
603 return false;
604 }
605
607
609 &dfbl->default_fb,
610 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
611
613 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
614
616 {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
617
618 return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) &&
621}
622
624 const char *viewname,
625 GPUFrameBuffer *fb,
626 const rcti *rect)
627{
629 if (rp) {
632 rect->xmin,
633 rect->ymin,
634 BLI_rcti_size_x(rect),
635 BLI_rcti_size_y(rect),
636 4,
637 0,
639 rp->ibuf->float_buffer.data);
640 }
641}
642
644 const char *viewname,
645 GPUFrameBuffer *fb,
646 const rcti *rect,
647 const float4x4 &winmat)
648{
649 RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_Z, viewname);
650 if (rp) {
653 rect->xmin,
654 rect->ymin,
655 BLI_rcti_size_x(rect),
656 BLI_rcti_size_y(rect),
658 rp->ibuf->float_buffer.data);
659
660 int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
661
662 /* Convert GPU depth [0..1] to view Z [near..far] */
663 if (blender::draw::View::default_get().is_persp()) {
664 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
665 if (z == 1.0f) {
666 z = 1e10f; /* Background */
667 }
668 else {
669 z = z * 2.0f - 1.0f;
670 z = winmat[3][2] / (z + winmat[2][2]);
671 }
672 }
673 }
674 else {
675 /* Keep in mind, near and far distance are negatives. */
678 float range = fabsf(far - near);
679
680 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
681 if (z == 1.0f) {
682 z = 1e10f; /* Background */
683 }
684 else {
685 z = z * range - near;
686 }
687 }
688 }
689 }
690}
691
692static void workbench_render_to_image(RenderEngine *engine, RenderLayer *layer, const rcti rect)
693{
694 using namespace blender::draw;
695 const DRWContext *draw_ctx = DRW_context_get();
696
697 if (!workbench_render_framebuffers_init(draw_ctx)) {
698 RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers");
699 return;
700 }
701
702 /* Setup */
704 Depsgraph *depsgraph = draw_ctx->depsgraph;
705
706 workbench::Instance instance;
707
708 /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
709 Object *camera_ob = DEG_get_evaluated(depsgraph, RE_GetCamera(engine->re));
710
711 /* Set the perspective, view and window matrix. */
712 float4x4 winmat, viewmat, viewinv;
713 RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
714 RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
715 viewmat = math::invert(viewinv);
716
717 /* Render */
718 /* TODO: Remove old draw manager calls. */
721
722 instance.init(depsgraph, camera_ob);
723
724 draw::Manager &manager = *DRW_manager_get();
725 manager.begin_sync();
726
727 instance.begin_sync();
729 engine,
730 depsgraph,
731 [&](blender::draw::ObjectRef &ob_ref, RenderEngine * /*engine*/, Depsgraph * /*depsgraph*/) {
732 instance.object_sync(ob_ref, manager);
733 });
734 instance.end_sync();
735
736 manager.end_sync();
737
739
741 instance.draw_image_render(manager, dtxl.depth, dtxl.depth_in_front, dtxl.color, engine);
742
744
745 /* Write image */
746 const char *viewname = RE_GetActiveRenderView(engine->re);
747 write_render_color_output(layer, viewname, dfbl->default_fb, &rect);
748 write_render_z_output(layer, viewname, dfbl->default_fb, &rect, winmat);
749}
750
752 Scene *scene,
753 ViewLayer *view_layer)
754{
755 if (view_layer->passflag & SCE_PASS_COMBINED) {
756 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
757 }
758 if (view_layer->passflag & SCE_PASS_Z) {
759 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT);
760 }
761}
762
763static void workbench_render(RenderEngine *engine, Depsgraph *depsgraph)
764{
766}
767
769 /*next*/ nullptr,
770 /*prev*/ nullptr,
771 /*idname*/ "BLENDER_WORKBENCH",
772 /*name*/ N_("Workbench"),
774 /*update*/ nullptr,
775 /*render*/ &workbench_render,
776 /*render_frame_finish*/ nullptr,
777 /*draw*/ nullptr,
778 /*bake*/ nullptr,
779 /*view_update*/ nullptr,
780 /*view_draw*/ nullptr,
781 /*update_script_node*/ nullptr,
782 /*update_render_passes*/ &workbench_render_update_passes,
783 /*update_custom_camera*/ nullptr,
784 /*draw_engine*/ nullptr,
785 /*rna_ext*/
786 {
787 /*data*/ nullptr,
788 /*srna*/ nullptr,
789 /*call*/ nullptr,
790 },
791};
792
General operations, lookup, etc. for materials.
Material * BKE_material_default_empty()
Material * BKE_object_material_get_eval(Object *ob, short act)
int BKE_object_material_used_with_fallback_eval(const Object &ob)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
General operations, lookup, etc. for blender objects.
@ OB_VISIBLE_SELF
A BVH for high poly meshes.
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ATTR_FALLTHROUGH
#define final(a, b, c)
Definition BLI_hash.h:19
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
uint64_t DEG_get_update_count(const Depsgraph *depsgraph)
Definition depsgraph.cc:355
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ FLUID_DOMAIN_TYPE_GAS
@ BASE_FROM_DUPLI
struct Material Material
@ eModifierMode_Realtime
@ eModifierType_ParticleSystem
@ eModifierType_Fluid
@ SOCK_FLOAT
@ SOCK_RGBA
@ OB_WIRE
@ OB_SOLID
@ OB_MODE_VERTEX_PAINT
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES
@ OB_DRAW_IN_FRONT
@ PART_DRAW_PATH
@ PART_DRAW_REND
#define RE_PASSNAME_COMBINED
#define RE_PASSNAME_Z
@ SCE_PASS_COMBINED
@ SCE_PASS_Z
eV3DShadingColorType
@ V3D_SHADING_TEXTURE_COLOR
@ V3D_SHADING_VERTEX_COLOR
@ V3D_SHADING_MATERIAL_COLOR
@ V3D_SHADING_OBJECT_COLOR
@ V3D_SHADING_RANDOM_COLOR
@ V3D_SHADING_SINGLE_COLOR
void DRW_submission_end()
void DRW_submission_start()
void GPU_render_step(bool force_resource_release=false)
eGPUBackendType GPU_backend_get_type()
void GPU_framebuffer_read_color(GPUFrameBuffer *fb, int x, int y, int width, int height, int channels, int slot, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_TEXTURE(_texture)
bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
void GPU_framebuffer_read_depth(GPUFrameBuffer *fb, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float(*clear_colors)[4])
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_flush()
Definition gpu_state.cc:305
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
@ GPU_DATA_FLOAT
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_GENERAL
@ GPU_R16UI
@ GPU_DEPTH24_STENCIL8
@ GPU_RGBA16F
@ RE_INTERNAL
Definition RE_engine.h:43
@ RE_USE_STEREO_VIEWPORT
Definition RE_engine.h:49
@ RE_USE_GPU_CONTEXT
Definition RE_engine.h:50
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
constexpr bool is_empty() const
Definition BLI_span.hh:260
void begin_sync(Object *object_active=nullptr)
ResourceHandleRange resource_handle(const ObjectRef &ref, float inflate_bounds=0.0f)
static void default_set(const float4x4 &view_mat, const float4x4 &win_mat)
Definition draw_view.cc:322
float near_clip(int view_id=0) const
Definition draw_view.hh:115
static View & default_get()
Definition draw_view.cc:317
float far_clip(int view_id=0) const
Definition draw_view.hh:106
A running instance of the engine.
void draw(Manager &manager) final
void draw(Manager &manager, GPUTexture *depth_tx, GPUTexture *depth_in_front_tx, GPUTexture *color_tx)
void draw_image_render(Manager &manager, GPUTexture *depth_tx, GPUTexture *depth_in_front_tx, GPUTexture *color_tx, RenderEngine *engine=nullptr)
Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot=0)
void object_sync(ObjectRef &ob_ref, Manager &manager) final
void draw_viewport(Manager &manager, GPUTexture *depth_tx, GPUTexture *depth_in_front_tx, GPUTexture *color_tx)
void draw_to_mesh_pass(ObjectRef &ob_ref, bool is_transparent, F draw_callback)
blender::StringRefNull name_get() final
Span< const GPUMaterial * > get_dummy_gpu_materials(int material_count)
void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
void init(Depsgraph *depsgraph, Object *camera_ob=nullptr)
void draw_mesh(ObjectRef &ob_ref, Material &material, gpu::Batch *batch, ResourceHandle handle, const MaterialTexture *texture=nullptr, bool show_missing_texture=false)
void sculpt_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
void mesh_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
void pointcloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
void hair_sync(Manager &manager, ObjectRef &ob_ref, ResourceHandle emitter_handle, const ObjectState &object_state, ParticleSystem *psys, ModifierData *md)
#define fabsf(x)
const DRWContext * DRW_context_get()
void DRW_cache_restart()
void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph, std::function< void(RenderEngine *, RenderLayer *, const rcti)> render_view_cb, std::function< void(RenderResult *)> store_metadata_cb)
void DRW_render_object_iter(RenderEngine *engine, Depsgraph *depsgraph, std::function< void(blender::draw::ObjectRef &, RenderEngine *, Depsgraph *)> callback)
bool DRW_object_is_renderable(const Object *ob)
int DRW_object_visibility_in_active_context(const Object *ob)
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
void DRW_viewport_request_redraw()
blender::draw::Manager * DRW_manager_get()
#define SCULPT_DEBUG_DRAW
struct @242053044010324116347033273112253060004051364061::@051143074301336237271216303350234260141112266062 batch
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define this
BLI_INLINE float fb(float length, float L)
void RE_GetCameraModelMatrix(const Render *re, const Object *camera, float r_modelmat[4][4])
void RE_GetCameraWindow(Render *re, const Object *camera, float r_winmat[4][4])
Object * RE_GetCamera(Render *re)
void RE_engine_report(RenderEngine *engine, int type, const char *msg)
bool RE_engine_test_break(RenderEngine *engine)
void RE_engine_register_pass(RenderEngine *engine, Scene *scene, ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2912
Bounds< float3 > bounds_get(const Tree &pbvh)
Definition pbvh.cc:1477
Span< gpu::Batch * > DRW_cache_mesh_surface_texpaint_get(Object *ob)
gpu::Batch * DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
gpu::Batch * DRW_cache_mesh_surface_vertpaint_get(Object *ob)
Vector< SculptBatch > sculpt_batches_get(const Object *ob, SculptBatchFeature features)
gpu::Batch * DRW_cache_object_surface_get(Object *ob)
@ SCULPT_BATCH_VERTEX_COLOR
Span< gpu::Batch * > DRW_cache_object_surface_material_get(Object *ob, const Span< const GPUMaterial * > materials)
gpu::Batch * DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
CartesianBasis invert(const CartesianBasis &basis)
T midpoint(const T &a, const T &b)
bool assign_if_different(T &old_value, T new_value)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 3 > float3
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
const char * RE_GetActiveRenderView(Render *re)
DefaultFramebufferList * viewport_framebuffer_list_get() const
Depsgraph * depsgraph
blender::float2 viewport_size_get() const
DefaultTextureList * viewport_texture_list_get() const
GPUFrameBuffer * depth_only_fb
GPUFrameBuffer * color_only_fb
GPUFrameBuffer * default_fb
GPUTexture * depth_in_front
struct FluidDomainSettings * domain
ImBufFloatBuffer float_buffer
void * first
short base_flag
ListBase modifiers
ParticleSettings * part
struct Render * re
Definition RE_engine.h:138
struct ImBuf * ibuf
Definition RE_pipeline.h:60
const c_style_mat & ptr() const
static void free_static()
DrawEngine * create_instance() final
float x
float y
int ymin
int xmin
i
Definition text_draw.cc:230
#define N_(msgid)
static void workbench_render(RenderEngine *engine, Depsgraph *depsgraph)
static void workbench_render_to_image(RenderEngine *engine, RenderLayer *layer, const rcti rect)
RenderEngineType DRW_engine_viewport_workbench_type
static bool workbench_render_framebuffers_init(const DRWContext *draw_ctx)
static void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
static void write_render_z_output(RenderLayer *layer, const char *viewname, GPUFrameBuffer *fb, const rcti *rect, const float4x4 &winmat)
static void write_render_color_output(RenderLayer *layer, const char *viewname, GPUFrameBuffer *fb, const rcti *rect)