Blender V5.0
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#include "BLI_string.h"
7
8#include "DNA_fluid_types.h"
9
10#include "BKE_editmesh.hh"
11#include "BKE_material.hh"
12#include "BKE_modifier.hh"
13#include "BKE_object.hh"
14#include "BKE_paint.hh"
15#include "BKE_paint_bvh.hh"
16#include "BKE_particle.h"
17#include "BKE_report.hh"
18
20
22#include "ED_paint.hh"
23#include "ED_view3d.hh"
24
25#include "BLT_translation.hh"
26
27#include "GPU_context.hh"
28#include "IMB_imbuf_types.hh"
29
30#include "RE_engine.h"
31#include "RE_pipeline.h"
32
33#include "draw_cache.hh"
34#include "draw_common.hh"
35#include "draw_sculpt.hh"
36#include "draw_view_data.hh"
37
38#include "workbench_private.hh"
39
40#include "workbench_engine.h" /* Own include. */
41
42namespace blender::workbench {
43
44using namespace draw;
45
46class Instance : public DrawEngine {
47 private:
48 View view_ = {"DefaultView"};
49
50 SceneState scene_state_;
51
52 SceneResources resources_;
53
54 OpaquePass opaque_ps_;
55 TransparentPass transparent_ps_;
56 TransparentDepthPass transparent_depth_ps_;
57
58 ShadowPass shadow_ps_;
59 VolumePass volume_ps_;
60 OutlinePass outline_ps_;
61 DofPass dof_ps_;
62 AntiAliasingPass anti_aliasing_ps_;
63
64 /* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get.
65 * They never get actually used. */
66 Vector<GPUMaterial *> dummy_gpu_materials_ = {1, nullptr, {}};
67
68 /* Used to detect any scene data update. */
69 uint64_t depsgraph_last_update_ = 0;
70
71 const char *hair_buffer_overflow_error_ = nullptr;
72
73 public:
74 const DRWContext *draw_ctx = nullptr;
75
77 {
78 return "Workbench";
79 }
80
82 {
83 if (material_count > dummy_gpu_materials_.size()) {
84 dummy_gpu_materials_.resize(material_count, nullptr);
85 }
86 return dummy_gpu_materials_.as_span().slice(IndexRange(material_count));
87 };
88
89 void init() final
90 {
91 this->draw_ctx = DRW_context_get();
92 init(draw_ctx->depsgraph);
93 }
94
95 void init(Depsgraph *depsgraph, Object *camera_ob = nullptr)
96 {
97 this->draw_ctx = DRW_context_get();
98 bool scene_updated = assign_if_different(depsgraph_last_update_,
100
101 scene_state_.init(this->draw_ctx, scene_updated, camera_ob);
102 shadow_ps_.init(scene_state_, resources_);
103 resources_.init(scene_state_, this->draw_ctx);
104
105 outline_ps_.init(scene_state_);
106 dof_ps_.init(scene_state_, this->draw_ctx);
107 anti_aliasing_ps_.init(scene_state_);
108 }
109
111 {
112 resources_.material_buf.clear_and_trim();
113
114 opaque_ps_.sync(scene_state_, resources_);
115 transparent_ps_.sync(scene_state_, resources_);
116 transparent_depth_ps_.sync(scene_state_, resources_);
117
118 shadow_ps_.sync();
119 volume_ps_.sync(resources_);
120 outline_ps_.sync(resources_);
121 dof_ps_.sync(resources_, this->draw_ctx);
122 anti_aliasing_ps_.sync(scene_state_, resources_);
123
124 hair_buffer_overflow_error_ = nullptr;
125 }
126
128 {
129 resources_.material_buf.push_update();
130 }
131
132 Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot = 0)
133 {
134 switch (color_type) {
136 return Material(*ob_ref.object);
138 return Material(*ob_ref.object, true);
140 return scene_state_.material_override;
142 return scene_state_.material_attribute_color;
146 if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, slot + 1)) {
147 return Material(*_mat);
148 }
150 default:
152 }
153 }
154
155 void object_sync(ObjectRef &ob_ref, Manager &manager) final
156 {
157 if (scene_state_.render_finished) {
158 return;
159 }
160
161 Object *ob = ob_ref.object;
162 if (!DRW_object_is_renderable(ob)) {
163 return;
164 }
165
166 const ObjectState object_state = ObjectState(this->draw_ctx, scene_state_, resources_, ob);
167
168 bool is_object_data_visible = (DRW_object_visibility_in_active_context(ob) &
170 (ob->dt >= OB_SOLID || draw_ctx->is_scene_render());
171
172 if (!(ob->base_flag & BASE_FROM_DUPLI)) {
174 if (md && BKE_modifier_is_enabled(scene_state_.scene, md, eModifierMode_Realtime)) {
176 if (fmd->domain) {
177 volume_ps_.object_sync_modifier(manager, resources_, scene_state_, ob_ref, md);
178
179 if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
180 /* Do not draw solid in this case. */
181 is_object_data_visible = false;
182 }
183 }
184 }
185 }
186
187 ResourceHandleRange emitter_handle = {};
188
189 if (is_object_data_visible) {
190 if (object_state.sculpt_pbvh) {
192 this->sculpt_sync(ob_ref, handle, object_state);
193 emitter_handle = handle;
194 }
195 else if (ob->type == OB_MESH) {
197 this->mesh_sync(ob_ref, handle, object_state);
198 emitter_handle = handle;
199 }
200 else if (ob->type == OB_POINTCLOUD) {
201 this->pointcloud_sync(manager, ob_ref, object_state);
202 }
203 else if (ob->type == OB_CURVES) {
204 this->curves_sync(manager, ob_ref, object_state);
205 }
206 else if (ob->type == OB_VOLUME) {
207 if (scene_state_.shading.type != OB_WIRE) {
208 volume_ps_.object_sync_volume(manager,
209 resources_,
210 scene_state_,
211 ob_ref,
212 get_material(ob_ref, object_state.color_type).base_color);
213 }
214 }
215 }
216
217 if (ob->type == OB_MESH && ob->modifiers.first != nullptr) {
219 if (md->type != eModifierType_ParticleSystem) {
220 continue;
221 }
222 ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
224 continue;
225 }
226 ParticleSettings *part = psys->part;
227 const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
228
229 if (draw_as == PART_DRAW_PATH) {
230 this->hair_sync(manager, ob_ref, emitter_handle, object_state, psys, md);
231 }
232 }
233 }
234 }
235
236 template<typename F>
237 void draw_to_mesh_pass(ObjectRef &ob_ref, bool is_transparent, F draw_callback)
238 {
239 const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0;
240
241 if (scene_state_.xray_mode || is_transparent) {
242 if (in_front) {
243 draw_callback(transparent_ps_.accumulation_in_front_ps_);
244 draw_callback(transparent_depth_ps_.in_front_ps_);
245 }
246 else {
247 draw_callback(transparent_ps_.accumulation_ps_);
248 draw_callback(transparent_depth_ps_.main_ps_);
249 }
250 }
251 else {
252 if (in_front) {
253 draw_callback(opaque_ps_.gbuffer_in_front_ps_);
254 }
255 else {
256 draw_callback(opaque_ps_.gbuffer_ps_);
257 }
258 }
259 }
260
261 void draw_mesh(ObjectRef &ob_ref,
262 Material &material,
263 gpu::Batch *batch,
264 ResourceHandleRange handle,
265 const MaterialTexture *texture = nullptr,
266 bool show_missing_texture = false)
267 {
268 resources_.material_buf.append(material);
269 int material_index = resources_.material_buf.size() - 1;
270
271 if (show_missing_texture && (!texture || !texture->gpu.texture)) {
272 texture = &resources_.missing_texture;
273 }
274
275 this->draw_to_mesh_pass(ob_ref, material.is_transparent(), [&](MeshPass &mesh_pass) {
276 mesh_pass.get_subpass(eGeometryType::MESH, texture).draw(batch, handle, material_index);
277 });
278 }
279
280 void mesh_sync(ObjectRef &ob_ref, ResourceHandleRange handle, const ObjectState &object_state)
281 {
282 bool has_transparent_material = false;
283
284 if (object_state.use_per_material_batches) {
285 const int material_count = BKE_object_material_used_with_fallback_eval(*ob_ref.object);
286
287 Span<gpu::Batch *> batches;
288 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
290 }
291 else {
293 ob_ref.object, this->get_dummy_gpu_materials(material_count));
294 }
295
296 if (!batches.is_empty()) {
297 for (auto i : IndexRange(material_count)) {
298 if (batches[i] == nullptr) {
299 continue;
300 }
301
302 int material_slot = i;
303 Material mat = this->get_material(ob_ref, object_state.color_type, material_slot);
304 has_transparent_material = has_transparent_material || mat.is_transparent();
305
307 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
308 texture = MaterialTexture(ob_ref.object, material_slot);
309 }
310
311 this->draw_mesh(
312 ob_ref, mat, batches[i], handle, &texture, object_state.show_missing_texture);
313 }
314 }
315 }
316 else {
317 gpu::Batch *batch;
318 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
320 }
321 else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
322 if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) {
324 }
325 else {
327 }
328 }
329 else {
331 }
332
333 if (batch) {
334 Material mat = this->get_material(ob_ref, object_state.color_type);
335 has_transparent_material = has_transparent_material || mat.is_transparent();
336
337 this->draw_mesh(ob_ref, mat, batch, handle, &object_state.image_paint_override);
338 }
339 }
340
341 if (object_state.draw_shadow) {
342 shadow_ps_.object_sync(scene_state_, ob_ref, handle, has_transparent_material);
343 }
344 }
345
346 void sculpt_sync(ObjectRef &ob_ref, ResourceHandleRange handle, const ObjectState &object_state)
347 {
349 if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
350 features = SCULPT_BATCH_VERTEX_COLOR;
351 }
352 else if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
353 features = SCULPT_BATCH_UV;
354 }
355
356 if (object_state.use_per_material_batches) {
357 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
358 Material mat = this->get_material(ob_ref, object_state.color_type, batch.material_slot);
359 if (SCULPT_DEBUG_DRAW) {
360 mat.base_color = batch.debug_color();
361 }
362
364 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
365 texture = MaterialTexture(ob_ref.object, batch.material_slot);
366 }
367
368 this->draw_mesh(
369 ob_ref, mat, batch.batch, handle, &texture, object_state.show_missing_texture);
370 }
371 }
372 else {
373 Material mat = this->get_material(ob_ref, object_state.color_type);
374 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
375 if (SCULPT_DEBUG_DRAW) {
376 mat.base_color = batch.debug_color();
377 }
378
379 this->draw_mesh(ob_ref, mat, batch.batch, handle, &object_state.image_paint_override);
380 }
381 }
382 }
383
384 void pointcloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
385 {
387
388 Material mat = this->get_material(ob_ref, object_state.color_type);
389 resources_.material_buf.append(mat);
390 int material_index = resources_.material_buf.size() - 1;
391
392 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
393 PassMain::Sub &pass =
394 mesh_pass.get_subpass(eGeometryType::POINTCLOUD).sub("Point Cloud SubPass");
395 gpu::Batch *batch = pointcloud_sub_pass_setup(pass, ob_ref.object);
396 pass.draw(batch, handle, material_index);
397 });
398 }
399
401 ObjectRef &ob_ref,
402 ResourceHandleRange emitter_handle,
403 const ObjectState &object_state,
404 ParticleSystem *psys,
405 ModifierData *md)
406 {
408 ob_ref, ob_ref.object->object_to_world());
409
410 Material mat = this->get_material(ob_ref, object_state.color_type, psys->part->omat - 1);
412 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
413 texture = MaterialTexture(ob_ref.object, psys->part->omat - 1);
414 }
415 resources_.material_buf.append(mat);
416 int material_index = resources_.material_buf.size() - 1;
417
418 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
419 PassMain::Sub &pass =
420 mesh_pass.get_subpass(eGeometryType::CURVES, &texture).sub("Hair SubPass");
421 pass.push_constant("emitter_object_id", int(emitter_handle.raw()));
422 gpu::Batch *batch = hair_sub_pass_setup(pass, scene_state_.scene, ob_ref, psys, md);
423 pass.draw(batch, handle, material_index);
424 });
425 }
426
427 void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
428 {
430
431 Material mat = this->get_material(ob_ref, object_state.color_type);
432 resources_.material_buf.append(mat);
433 int material_index = resources_.material_buf.size() - 1;
434
435 this->draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
436 PassMain::Sub &pass = mesh_pass.get_subpass(eGeometryType::CURVES).sub("Curves SubPass");
437
438 const char *error = nullptr;
439 gpu::Batch *batch = curves_sub_pass_setup(pass, scene_state_.scene, ob_ref.object, error);
440 if (error) {
441 hair_buffer_overflow_error_ = error;
442 }
443 pass.draw(batch, handle, material_index);
444 });
445 }
446
447 void draw(Manager &manager,
448 gpu::Texture *depth_tx,
449 gpu::Texture *depth_in_front_tx,
450 gpu::Texture *color_tx)
451 {
452 int2 resolution = scene_state_.resolution;
453
456 bool needs_depth_in_front = !transparent_ps_.accumulation_in_front_ps_.is_empty() ||
457 (!opaque_ps_.gbuffer_in_front_ps_.is_empty() &&
458 scene_state_.sample == 0);
459 resources_.depth_in_front_tx.wrap(needs_depth_in_front ? depth_in_front_tx : nullptr);
460 if (!needs_depth_in_front || opaque_ps_.gbuffer_in_front_ps_.is_empty()) {
461 resources_.clear_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_in_front_tx));
462 resources_.clear_in_front_fb.bind();
463 GPU_framebuffer_clear_depth_stencil(resources_.clear_in_front_fb, 1.0f, 0x00);
464 }
465
466 resources_.depth_tx.wrap(depth_tx);
467 resources_.color_tx.wrap(color_tx);
468
469 if (scene_state_.render_finished) {
470 /* Just copy back the already rendered result */
471 anti_aliasing_ps_.draw(
472 draw_ctx, manager, View::default_get(), scene_state_, resources_, depth_in_front_tx);
473 return;
474 }
475
476 anti_aliasing_ps_.setup_view(view_, scene_state_);
477
478 GPUAttachment id_attachment = GPU_ATTACHMENT_NONE;
479 if (scene_state_.draw_object_id) {
480 resources_.object_id_tx.acquire(resolution,
481 gpu::TextureFormat::UINT_16,
484 id_attachment = GPU_ATTACHMENT_TEXTURE(resources_.object_id_tx);
485 }
486 resources_.clear_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources_.depth_tx),
487 GPU_ATTACHMENT_TEXTURE(resources_.color_tx),
488 id_attachment);
489 resources_.clear_fb.bind();
490 float4 clear_colors[2] = {scene_state_.background_color, float4(0.0f)};
491 GPU_framebuffer_multi_clear(resources_.clear_fb, reinterpret_cast<float (*)[4]>(clear_colors));
492 GPU_framebuffer_clear_depth_stencil(resources_.clear_fb, 1.0f, 0x00);
493
494 opaque_ps_.draw(
495 manager, view_, resources_, resolution, scene_state_.draw_shadows ? &shadow_ps_ : nullptr);
496 transparent_ps_.draw(manager, view_, resources_, resolution);
497 transparent_depth_ps_.draw(manager, view_, resources_);
498
499 volume_ps_.draw(manager, view_, resources_);
500 outline_ps_.draw(manager, resources_);
501 dof_ps_.draw(manager, view_, resources_, resolution);
502 anti_aliasing_ps_.draw(draw_ctx, manager, view_, scene_state_, resources_, depth_in_front_tx);
503
504 resources_.object_id_tx.release();
505 }
506
507 void draw_viewport(Manager &manager,
508 gpu::Texture *depth_tx,
509 gpu::Texture *depth_in_front_tx,
510 gpu::Texture *color_tx)
511 {
512 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
513
514 if (scene_state_.sample + 1 < scene_state_.samples_len) {
516 }
517
518 if (hair_buffer_overflow_error_) {
519 STRNCPY(info, hair_buffer_overflow_error_);
520 }
521 else {
522 STRNCPY(info, "");
523 }
524 }
525
526 void draw(Manager &manager) final
527 {
528 DefaultTextureList *dtxl = draw_ctx->viewport_texture_list_get();
529
531 if (draw_ctx->is_viewport_image_render()) {
532 draw_image_render(manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
533 }
534 else {
535 draw_viewport(manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
536 }
538 }
539
541 gpu::Texture *depth_tx,
542 gpu::Texture *depth_in_front_tx,
543 gpu::Texture *color_tx,
544 RenderEngine *engine = nullptr)
545 {
546 if (scene_state_.render_finished) {
547 /* This can happen in viewport animation renders, if the scene didn't have any updates
548 * between frames. */
549 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
550 return;
551 }
552
553 BLI_assert(scene_state_.sample == 0);
554 for (auto i : IndexRange(scene_state_.samples_len)) {
555 if (hair_buffer_overflow_error_) {
556 RE_engine_set_error_message(engine, hair_buffer_overflow_error_);
557 }
558
559 if (engine && RE_engine_test_break(engine)) {
560 break;
561 }
562 if (i != 0) {
563 scene_state_.sample = i;
564 /* Re-sync anything dependent on scene_state.sample. */
565 resources_.init(scene_state_, draw_ctx);
566 dof_ps_.init(scene_state_, draw_ctx);
567 anti_aliasing_ps_.sync(scene_state_, resources_);
568 }
569 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
570 /* Perform render step between samples to allow
571 * flushing of freed GPUBackend resources. */
573 GPU_flush();
574 }
576 }
577 }
578};
579
580DrawEngine *Engine::create_instance()
581{
582 return new Instance();
583}
584
585void Engine::free_static()
586{
587 ShaderCache::release();
588}
589
590} // namespace blender::workbench
591
592/* -------------------------------------------------------------------- */
595
596using namespace blender;
597
598/* RENDER */
599
601{
602 /* For image render, allocate own buffers because we don't have a viewport. */
603 const float2 viewport_size = draw_ctx->viewport_size_get();
604 const int2 size = {int(viewport_size.x), int(viewport_size.y)};
605
607
608 /* When doing a multi view rendering the first view will allocate the buffers
609 * the other views will reuse these buffers */
610 if (dtxl->color == nullptr) {
611 BLI_assert(dtxl->depth == nullptr);
614 "txl.color", size.x, size.y, 1, gpu::TextureFormat::SFLOAT_16_16_16_16, usage, nullptr);
615 dtxl->depth = GPU_texture_create_2d("txl.depth",
616 size.x,
617 size.y,
618 1,
619 gpu::TextureFormat::SFLOAT_32_DEPTH_UINT_8,
620 usage,
621 nullptr);
622 dtxl->depth_in_front = GPU_texture_create_2d("txl.depth_in_front",
623 size.x,
624 size.y,
625 1,
626 gpu::TextureFormat::SFLOAT_32_DEPTH_UINT_8,
627 usage,
628 nullptr);
629 }
630
631 if (!(dtxl->depth && dtxl->color && dtxl->depth_in_front)) {
632 return false;
633 }
634
636
638 &dfbl->default_fb,
639 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
640
642 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
643
645 {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
646
647 return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) &&
650}
651
653 const char *viewname,
655 const rcti *rect)
656{
658 if (rp) {
661 rect->xmin,
662 rect->ymin,
663 BLI_rcti_size_x(rect),
664 BLI_rcti_size_y(rect),
665 4,
666 0,
668 rp->ibuf->float_buffer.data);
669 }
670}
671
673 const char *viewname,
675 const rcti *rect,
676 const float4x4 &winmat)
677{
678 RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_DEPTH, viewname);
679 if (rp) {
682 rect->xmin,
683 rect->ymin,
684 BLI_rcti_size_x(rect),
685 BLI_rcti_size_y(rect),
687 rp->ibuf->float_buffer.data);
688
689 int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
690
691 /* Convert GPU depth [0..1] to view Z [near..far] */
692 if (blender::draw::View::default_get().is_persp()) {
693 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
694 if (z == 1.0f) {
695 z = 1e10f; /* Background */
696 }
697 else {
698 z = z * 2.0f - 1.0f;
699 z = winmat[3][2] / (z + winmat[2][2]);
700 }
701 }
702 }
703 else {
704 /* Keep in mind, near and far distance are negatives. */
707 float range = fabsf(far - near);
708
709 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
710 if (z == 1.0f) {
711 z = 1e10f; /* Background */
712 }
713 else {
714 z = z * range - near;
715 }
716 }
717 }
718 }
719}
720
721static void workbench_render_to_image(RenderEngine *engine, RenderLayer *layer, const rcti rect)
722{
723 using namespace blender::draw;
724 const DRWContext *draw_ctx = DRW_context_get();
725
726 if (!workbench_render_framebuffers_init(draw_ctx)) {
727 RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers");
728 return;
729 }
730
731 /* Setup */
733 Depsgraph *depsgraph = draw_ctx->depsgraph;
734
735 workbench::Instance instance;
736
737 /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
738 Object *camera_ob = DEG_get_evaluated(depsgraph, RE_GetCamera(engine->re));
739
740 /* Set the perspective, view and window matrix. */
741 float4x4 winmat, viewmat, viewinv;
742 RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
743 RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
744 viewmat = math::invert(viewinv);
745
746 /* Render */
747 /* TODO: Remove old draw manager calls. */
750
751 instance.init(depsgraph, camera_ob);
752
753 draw::Manager &manager = *DRW_manager_get();
754 manager.begin_sync();
755
756 instance.begin_sync();
758 engine,
759 depsgraph,
760 [&](blender::draw::ObjectRef &ob_ref, RenderEngine * /*engine*/, Depsgraph * /*depsgraph*/) {
761 instance.object_sync(ob_ref, manager);
762 });
763 instance.end_sync();
764
765 manager.end_sync();
766
768
770 instance.draw_image_render(manager, dtxl.depth, dtxl.depth_in_front, dtxl.color, engine);
771
773
774 /* Write image */
775 const char *viewname = RE_GetActiveRenderView(engine->re);
776 write_render_color_output(layer, viewname, dfbl->default_fb, &rect);
777 write_render_z_output(layer, viewname, dfbl->default_fb, &rect, winmat);
778}
779
781 Scene *scene,
782 ViewLayer *view_layer)
783{
784 if (view_layer->passflag & SCE_PASS_COMBINED) {
785 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
786 }
787 if (view_layer->passflag & SCE_PASS_DEPTH) {
788 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_DEPTH, 1, "Z", SOCK_FLOAT);
789 }
790}
791
792static void workbench_render(RenderEngine *engine, Depsgraph *depsgraph)
793{
795}
796
798 /*next*/ nullptr,
799 /*prev*/ nullptr,
800 /*idname*/ "BLENDER_WORKBENCH",
801 /*name*/ N_("Workbench"),
803 /*update*/ nullptr,
804 /*render*/ &workbench_render,
805 /*render_frame_finish*/ nullptr,
806 /*draw*/ nullptr,
807 /*bake*/ nullptr,
808 /*view_update*/ nullptr,
809 /*view_draw*/ nullptr,
810 /*update_script_node*/ nullptr,
811 /*update_render_passes*/ &workbench_render_update_passes,
812 /*update_custom_camera*/ nullptr,
813 /*draw_engine*/ nullptr,
814 /*rna_ext*/
815 {
816 /*data*/ nullptr,
817 /*srna*/ nullptr,
818 /*call*/ nullptr,
819 },
820};
821
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.
@ RPT_ERROR
Definition BKE_report.hh:39
#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
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
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_DRAW_IN_FRONT
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES
@ PART_DRAW_PATH
@ PART_DRAW_REND
#define RE_PASSNAME_COMBINED
#define RE_PASSNAME_DEPTH
@ SCE_PASS_COMBINED
@ SCE_PASS_DEPTH
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)
GPUBackendType GPU_backend_get_type()
#define GPU_ATTACHMENT_TEXTURE(_texture)
void GPU_framebuffer_clear_depth_stencil(blender::gpu::FrameBuffer *fb, float clear_depth, uint clear_stencil)
void GPU_framebuffer_read_color(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height, int channels, int slot, eGPUDataFormat data_format, void *r_data)
void GPU_framebuffer_multi_clear(blender::gpu::FrameBuffer *fb, const float(*clear_colors)[4])
#define GPU_ATTACHMENT_NONE
bool GPU_framebuffer_check_valid(blender::gpu::FrameBuffer *fb, char err_out[256])
void GPU_framebuffer_read_depth(blender::gpu::FrameBuffer *fb, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_framebuffer_bind(blender::gpu::FrameBuffer *fb)
void GPU_flush()
Definition gpu_state.cc:305
@ GPU_DATA_FLOAT
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_GENERAL
blender::gpu::Texture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
@ 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)
ResourceHandle resource_handle_for_psys(const ObjectRef &ref, const float4x4 &model_matrix)
ResourceHandleRange unique_handle_for_sculpt(const ObjectRef &ref)
ResourceHandleRange unique_handle(const ObjectRef &ref)
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 hair_sync(Manager &manager, ObjectRef &ob_ref, ResourceHandleRange emitter_handle, const ObjectState &object_state, ParticleSystem *psys, ModifierData *md)
void draw(Manager &manager) final
void mesh_sync(ObjectRef &ob_ref, ResourceHandleRange handle, const ObjectState &object_state)
void draw_viewport(Manager &manager, gpu::Texture *depth_tx, gpu::Texture *depth_in_front_tx, gpu::Texture *color_tx)
void draw_mesh(ObjectRef &ob_ref, Material &material, gpu::Batch *batch, ResourceHandleRange handle, const MaterialTexture *texture=nullptr, bool show_missing_texture=false)
Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot=0)
void draw(Manager &manager, gpu::Texture *depth_tx, gpu::Texture *depth_in_front_tx, gpu::Texture *color_tx)
void object_sync(ObjectRef &ob_ref, Manager &manager) final
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 draw_image_render(Manager &manager, gpu::Texture *depth_tx, gpu::Texture *depth_in_front_tx, gpu::Texture *color_tx, RenderEngine *engine=nullptr)
void init(Depsgraph *depsgraph, Object *camera_ob=nullptr)
void sculpt_sync(ObjectRef &ob_ref, ResourceHandleRange handle, const ObjectState &object_state)
void pointcloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
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 @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
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_set_error_message(RenderEngine *engine, const char *msg)
void RE_engine_register_pass(RenderEngine *engine, Scene *scene, ViewLayer *view_layer, const char *name, int channels, const char *chanid, eNodeSocketDatatype type)
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)
bool assign_if_different(T &old_value, T new_value)
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
#define fabsf
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
blender::gpu::FrameBuffer * default_fb
blender::gpu::FrameBuffer * color_only_fb
blender::gpu::FrameBuffer * depth_only_fb
blender::gpu::Texture * depth
blender::gpu::Texture * color
blender::gpu::Texture * depth_in_front
char info[GPU_INFO_SIZE]
Definition DRW_render.hh:72
struct FluidDomainSettings * domain
ImBufFloatBuffer float_buffer
void * first
short base_flag
ListBase modifiers
ParticleSettings * part
struct Render * re
Definition RE_engine.h:137
struct ImBuf * ibuf
Definition RE_pipeline.h:67
const c_style_mat & ptr() const
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, gpu::FrameBuffer *fb, const rcti *rect, const float4x4 &winmat)
static void write_render_color_output(RenderLayer *layer, const char *viewname, gpu::FrameBuffer *fb, const rcti *rect)