Blender V4.3
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 "BKE_editmesh.hh"
6#include "BKE_modifier.hh"
7#include "BKE_object.hh"
8#include "BKE_paint.hh"
9#include "BKE_particle.h"
10#include "BKE_pbvh_api.hh"
11#include "BKE_report.hh"
13#include "DNA_fluid_types.h"
14#include "ED_paint.hh"
15#include "ED_view3d.hh"
16#include "GPU_capabilities.hh"
17#include "IMB_imbuf_types.hh"
18
19#include "draw_common.hh"
20#include "draw_sculpt.hh"
21
22#include "workbench_private.hh"
23
24#include "workbench_engine.h" /* Own include. */
25
26namespace blender::workbench {
27
28using namespace draw;
29
30class Instance {
31 public:
32 View view = {"DefaultView"};
33
35
37
41
47
48 /* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get.
49 * They never get actually used. */
52 {
53 if (material_count > dummy_gpu_materials.size()) {
54 dummy_gpu_materials.resize(material_count, nullptr);
55 }
56 return dummy_gpu_materials.begin();
57 };
58
59 void init(Object *camera_ob = nullptr)
60 {
61 scene_state.init(camera_ob);
62 shadow_ps.init(scene_state, resources);
63 resources.init(scene_state);
64
65 outline_ps.init(scene_state);
66 dof_ps.init(scene_state);
67 anti_aliasing_ps.init(scene_state);
68 }
69
71 {
72 resources.material_buf.clear_and_trim();
73
74 opaque_ps.sync(scene_state, resources);
75 transparent_ps.sync(scene_state, resources);
76 transparent_depth_ps.sync(scene_state, resources);
77
78 shadow_ps.sync();
79 volume_ps.sync(resources);
80 outline_ps.sync(resources);
81 dof_ps.sync(resources);
82 anti_aliasing_ps.sync(scene_state, resources);
83 }
84
85 void end_sync()
86 {
87 resources.material_buf.push_update();
88 }
89
90 Material get_material(ObjectRef ob_ref, eV3DShadingColorType color_type, int slot = 0)
91 {
92 switch (color_type) {
94 return Material(*ob_ref.object);
96 return Material(*ob_ref.object, true);
98 return scene_state.material_override;
100 return scene_state.material_attribute_color;
104 if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, slot + 1)) {
105 return Material(*_mat);
106 }
108 default:
110 }
111 }
112
114 {
115 if (scene_state.render_finished) {
116 return;
117 }
118
119 Object *ob = ob_ref.object;
120 if (!DRW_object_is_renderable(ob)) {
121 return;
122 }
123
124 const ObjectState object_state = ObjectState(scene_state, resources, ob);
125
126 bool is_object_data_visible = (DRW_object_visibility_in_active_context(ob) &
129
130 if (!(ob->base_flag & BASE_FROM_DUPLI)) {
132 if (md && BKE_modifier_is_enabled(scene_state.scene, md, eModifierMode_Realtime)) {
134 if (fmd->domain) {
135 volume_ps.object_sync_modifier(manager, resources, scene_state, ob_ref, md);
136
137 if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) {
138 /* Do not draw solid in this case. */
139 is_object_data_visible = false;
140 }
141 }
142 }
143 }
144
145 ResourceHandle emitter_handle(0);
146
147 if (is_object_data_visible) {
148 if (object_state.sculpt_pbvh) {
150 *bke::object::pbvh_get(*ob_ref.object));
151 const float3 center = math::midpoint(bounds.min, bounds.max);
152 const float3 half_extent = bounds.max - center;
153 ResourceHandle handle = manager.resource_handle(ob_ref, nullptr, &center, &half_extent);
154 sculpt_sync(ob_ref, handle, object_state);
155 emitter_handle = handle;
156 }
157 else if (ob->type == OB_MESH) {
158 ResourceHandle handle = manager.resource_handle(ob_ref);
159 mesh_sync(ob_ref, handle, object_state);
160 emitter_handle = handle;
161 }
162 else if (ob->type == OB_POINTCLOUD) {
163 point_cloud_sync(manager, ob_ref, object_state);
164 }
165 else if (ob->type == OB_CURVES) {
166 curves_sync(manager, ob_ref, object_state);
167 }
168 else if (ob->type == OB_VOLUME) {
169 if (scene_state.shading.type != OB_WIRE) {
170 volume_ps.object_sync_volume(manager,
171 resources,
172 scene_state,
173 ob_ref,
174 get_material(ob_ref, object_state.color_type).base_color);
175 }
176 }
177 }
178
179 if (ob->type == OB_MESH && ob->modifiers.first != nullptr) {
181 if (md->type != eModifierType_ParticleSystem) {
182 continue;
183 }
184 ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys;
186 continue;
187 }
188 ParticleSettings *part = psys->part;
189 const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
190
191 if (draw_as == PART_DRAW_PATH) {
192 hair_sync(manager, ob_ref, emitter_handle, object_state, psys, md);
193 }
194 }
195 }
196 }
197
198 template<typename F>
199 void draw_to_mesh_pass(ObjectRef &ob_ref, bool is_transparent, F draw_callback)
200 {
201 const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0;
202
203 if (scene_state.xray_mode || is_transparent) {
204 if (in_front) {
205 draw_callback(transparent_ps.accumulation_in_front_ps_);
206 draw_callback(transparent_depth_ps.in_front_ps_);
207 }
208 else {
209 draw_callback(transparent_ps.accumulation_ps_);
210 draw_callback(transparent_depth_ps.main_ps_);
211 }
212 }
213 else {
214 if (in_front) {
215 draw_callback(opaque_ps.gbuffer_in_front_ps_);
216 }
217 else {
218 draw_callback(opaque_ps.gbuffer_ps_);
219 }
220 }
221 }
222
223 void draw_mesh(ObjectRef &ob_ref,
224 Material &material,
225 gpu::Batch *batch,
226 ResourceHandle handle,
227 const MaterialTexture *texture = nullptr,
228 bool show_missing_texture = false)
229 {
230 resources.material_buf.append(material);
231 int material_index = resources.material_buf.size() - 1;
232
233 if (show_missing_texture && (!texture || !texture->gpu.texture)) {
234 texture = &resources.missing_texture;
235 }
236
237 draw_to_mesh_pass(ob_ref, material.is_transparent(), [&](MeshPass &mesh_pass) {
238 mesh_pass.get_subpass(eGeometryType::MESH, texture).draw(batch, handle, material_index);
239 });
240 }
241
242 void mesh_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
243 {
244 bool has_transparent_material = false;
245
246 if (object_state.use_per_material_batches) {
247 const int material_count = DRW_cache_object_material_count_get(ob_ref.object);
248
249 gpu::Batch **batches;
250 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
252 }
253 else {
255 ob_ref.object, get_dummy_gpu_materials(material_count), material_count);
256 }
257
258 if (batches) {
259 for (auto i : IndexRange(material_count)) {
260 if (batches[i] == nullptr) {
261 continue;
262 }
263
264 int material_slot = i;
265 Material mat = get_material(ob_ref, object_state.color_type, material_slot);
266 has_transparent_material = has_transparent_material || mat.is_transparent();
267
269 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
270 texture = MaterialTexture(ob_ref.object, material_slot);
271 }
272
273 draw_mesh(ob_ref, mat, batches[i], handle, &texture, object_state.show_missing_texture);
274 }
275 }
276 }
277 else {
278 gpu::Batch *batch;
279 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
281 }
282 else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
283 if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) {
285 }
286 else {
288 }
289 }
290 else {
292 }
293
294 if (batch) {
295 Material mat = get_material(ob_ref, object_state.color_type);
296 has_transparent_material = has_transparent_material || mat.is_transparent();
297
298 draw_mesh(ob_ref, mat, batch, handle, &object_state.image_paint_override);
299 }
300 }
301
302 if (object_state.draw_shadow) {
303 shadow_ps.object_sync(scene_state, ob_ref, handle, has_transparent_material);
304 }
305 }
306
307 void sculpt_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
308 {
310 if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) {
311 features = SCULPT_BATCH_VERTEX_COLOR;
312 }
313 else if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
314 features = SCULPT_BATCH_UV;
315 }
316
317 if (object_state.use_per_material_batches) {
318 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
319 Material mat = get_material(ob_ref, object_state.color_type, batch.material_slot);
320 if (SCULPT_DEBUG_DRAW) {
321 mat.base_color = batch.debug_color();
322 }
323
325 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
326 texture = MaterialTexture(ob_ref.object, batch.material_slot);
327 }
328
329 draw_mesh(ob_ref, mat, batch.batch, handle, &texture, object_state.show_missing_texture);
330 }
331 }
332 else {
333 Material mat = get_material(ob_ref, object_state.color_type);
334 for (SculptBatch &batch : sculpt_batches_get(ob_ref.object, features)) {
335 if (SCULPT_DEBUG_DRAW) {
336 mat.base_color = batch.debug_color();
337 }
338
339 draw_mesh(ob_ref, mat, batch.batch, handle, &object_state.image_paint_override);
340 }
341 }
342 }
343
344 void point_cloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
345 {
346 ResourceHandle handle = manager.resource_handle(ob_ref);
347
348 Material mat = get_material(ob_ref, object_state.color_type);
349 resources.material_buf.append(mat);
350 int material_index = resources.material_buf.size() - 1;
351
352 draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
353 PassMain::Sub &pass =
354 mesh_pass.get_subpass(eGeometryType::POINTCLOUD).sub("Point Cloud SubPass");
355 gpu::Batch *batch = point_cloud_sub_pass_setup(pass, ob_ref.object);
356 pass.draw(batch, handle, material_index);
357 });
358 }
359
361 ObjectRef &ob_ref,
362 ResourceHandle emitter_handle,
363 const ObjectState &object_state,
364 ParticleSystem *psys,
365 ModifierData *md)
366 {
367 /* Skip frustum culling. */
368 ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world());
369
370 Material mat = get_material(ob_ref, object_state.color_type, psys->part->omat - 1);
372 if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) {
373 texture = MaterialTexture(ob_ref.object, psys->part->omat - 1);
374 }
375 resources.material_buf.append(mat);
376 int material_index = resources.material_buf.size() - 1;
377
378 draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
379 PassMain::Sub &pass =
380 mesh_pass.get_subpass(eGeometryType::CURVES, &texture).sub("Hair SubPass");
381 pass.push_constant("emitter_object_id", int(emitter_handle.raw));
382 gpu::Batch *batch = hair_sub_pass_setup(pass, scene_state.scene, ob_ref.object, psys, md);
383 pass.draw(batch, handle, material_index);
384 });
385 }
386
387 void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
388 {
389 /* Skip frustum culling. */
390 ResourceHandle handle = manager.resource_handle(ob_ref.object->object_to_world());
391
392 Material mat = get_material(ob_ref, object_state.color_type);
393 resources.material_buf.append(mat);
394 int material_index = resources.material_buf.size() - 1;
395
396 draw_to_mesh_pass(ob_ref, mat.is_transparent(), [&](MeshPass &mesh_pass) {
397 PassMain::Sub &pass = mesh_pass.get_subpass(eGeometryType::CURVES).sub("Curves SubPass");
398 gpu::Batch *batch = curves_sub_pass_setup(pass, scene_state.scene, ob_ref.object);
399 pass.draw(batch, handle, material_index);
400 });
401 }
402
404 GPUTexture *depth_tx,
405 GPUTexture *depth_in_front_tx,
406 GPUTexture *color_tx)
407 {
408 view.sync(DRW_view_default_get());
409
410 int2 resolution = scene_state.resolution;
411
414 bool needs_depth_in_front = !transparent_ps.accumulation_in_front_ps_.is_empty() ||
415 (!opaque_ps.gbuffer_in_front_ps_.is_empty() &&
416 scene_state.sample == 0);
417 resources.depth_in_front_tx.wrap(needs_depth_in_front ? depth_in_front_tx : nullptr);
418 if (!needs_depth_in_front || opaque_ps.gbuffer_in_front_ps_.is_empty()) {
419 resources.clear_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_in_front_tx));
420 resources.clear_in_front_fb.bind();
422 }
423
424 resources.depth_tx.wrap(depth_tx);
425 resources.color_tx.wrap(color_tx);
426
427 if (scene_state.render_finished) {
428 /* Just copy back the already rendered result */
429 anti_aliasing_ps.draw(manager, view, scene_state, resources, depth_in_front_tx);
430 return;
431 }
432
433 anti_aliasing_ps.setup_view(view, scene_state);
434
435 GPUAttachment id_attachment = GPU_ATTACHMENT_NONE;
436 if (scene_state.draw_object_id) {
437 resources.object_id_tx.acquire(
439 id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
440 }
441 resources.clear_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
443 id_attachment);
444 resources.clear_fb.bind();
445 float4 clear_colors[2] = {scene_state.background_color, float4(0.0f)};
446 GPU_framebuffer_multi_clear(resources.clear_fb, reinterpret_cast<float(*)[4]>(clear_colors));
447 GPU_framebuffer_clear_depth_stencil(resources.clear_fb, 1.0f, 0x00);
448
449 opaque_ps.draw(
450 manager, view, resources, resolution, scene_state.draw_shadows ? &shadow_ps : nullptr);
451 transparent_ps.draw(manager, view, resources, resolution);
452 transparent_depth_ps.draw(manager, view, resources);
453
454 volume_ps.draw(manager, view, resources);
455 outline_ps.draw(manager, resources);
456 dof_ps.draw(manager, view, resources, resolution);
457 anti_aliasing_ps.draw(manager, view, scene_state, resources, depth_in_front_tx);
458
459 resources.object_id_tx.release();
460 }
461
463 GPUTexture *depth_tx,
464 GPUTexture *depth_in_front_tx,
465 GPUTexture *color_tx)
466 {
467 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
468
469 if (scene_state.sample + 1 < scene_state.samples_len) {
471 }
472 }
473
475 GPUTexture *depth_tx,
476 GPUTexture *depth_in_front_tx,
477 GPUTexture *color_tx,
478 RenderEngine *engine = nullptr)
479 {
480 BLI_assert(scene_state.sample == 0);
481 for (auto i : IndexRange(scene_state.samples_len)) {
482 if (engine && RE_engine_test_break(engine)) {
483 break;
484 }
485 if (i != 0) {
486 scene_state.sample = i;
487 /* Re-sync anything dependent on scene_state.sample. */
488 resources.init(scene_state);
489 dof_ps.init(scene_state);
490 anti_aliasing_ps.sync(scene_state, resources);
491 }
492 this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
493 /* Perform render step between samples to allow
494 * flushing of freed GPUBackend resources. */
496 GPU_flush();
497 }
499 }
500 }
501};
502
503} // namespace blender::workbench
504
505/* -------------------------------------------------------------------- */
509using namespace blender;
510
521
522static void workbench_engine_init(void *vedata)
523{
524 WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
525 if (ved->instance == nullptr) {
526 ved->instance = new workbench::Instance();
527 }
528
529 ved->instance->init();
530}
531
532static void workbench_cache_init(void *vedata)
533{
534 reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->begin_sync();
535}
536
537static void workbench_cache_populate(void *vedata, Object *object)
538{
539 draw::Manager *manager = DRW_manager_get();
540
541 draw::ObjectRef ref;
542 ref.object = object;
545
546 reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->object_sync(*manager, ref);
547}
548
549static void workbench_cache_finish(void *vedata)
550{
551 reinterpret_cast<WORKBENCH_Data *>(vedata)->instance->end_sync();
552}
553
554static void workbench_draw_scene(void *vedata)
555{
556 WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
558 draw::Manager *manager = DRW_manager_get();
560 ved->instance->draw_image_render(*manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
561 }
562 else {
563 ved->instance->draw_viewport(*manager, dtxl->depth, dtxl->depth_in_front, dtxl->color);
564 }
565}
566
567static void workbench_instance_free(void *instance)
568{
569 delete reinterpret_cast<workbench::Instance *>(instance);
570}
571
576
577static void workbench_view_update(void *vedata)
578{
579 WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
580 if (ved->instance) {
582 }
583}
584
585static void workbench_id_update(void *vedata, ID *id)
586{
587 UNUSED_VARS(vedata, id);
588}
589
590/* RENDER */
591
593{
594 /* For image render, allocate own buffers because we don't have a viewport. */
595 const float2 viewport_size = DRW_viewport_size_get();
596 const int2 size = {int(viewport_size.x), int(viewport_size.y)};
597
599
600 /* When doing a multi view rendering the first view will allocate the buffers
601 * the other views will reuse these buffers */
602 if (dtxl->color == nullptr) {
603 BLI_assert(dtxl->depth == nullptr);
606 "txl.color", size.x, size.y, 1, GPU_RGBA16F, usage, nullptr);
608 "txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
610 "txl.depth_in_front", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
611 }
612
613 if (!(dtxl->depth && dtxl->color && dtxl->depth_in_front)) {
614 return false;
615 }
616
618
620 &dfbl->default_fb,
621 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
622
624 {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE});
625
627 {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)});
628
629 return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) &&
632}
633
635 const char *viewname,
636 GPUFrameBuffer *fb,
637 const rcti *rect)
638{
640 if (rp) {
643 rect->xmin,
644 rect->ymin,
645 BLI_rcti_size_x(rect),
646 BLI_rcti_size_y(rect),
647 4,
648 0,
650 rp->ibuf->float_buffer.data);
651 }
652}
653
655 const char *viewname,
656 GPUFrameBuffer *fb,
657 const rcti *rect,
658 const float4x4 &winmat)
659{
660 RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_Z, viewname);
661 if (rp) {
664 rect->xmin,
665 rect->ymin,
666 BLI_rcti_size_x(rect),
667 BLI_rcti_size_y(rect),
669 rp->ibuf->float_buffer.data);
670
671 int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect);
672
673 /* Convert GPU depth [0..1] to view Z [near..far] */
674 if (DRW_view_is_persp_get(nullptr)) {
675 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
676 if (z == 1.0f) {
677 z = 1e10f; /* Background */
678 }
679 else {
680 z = z * 2.0f - 1.0f;
681 z = winmat[3][2] / (z + winmat[2][2]);
682 }
683 }
684 }
685 else {
686 /* Keep in mind, near and far distance are negatives. */
687 float near = DRW_view_near_distance_get(nullptr);
688 float far = DRW_view_far_distance_get(nullptr);
689 float range = fabsf(far - near);
690
691 for (float &z : MutableSpan(rp->ibuf->float_buffer.data, pix_num)) {
692 if (z == 1.0f) {
693 z = 1e10f; /* Background */
694 }
695 else {
696 z = z * range - near;
697 }
698 }
699 }
700 }
701}
702
703static void workbench_render_to_image(void *vedata,
704 RenderEngine *engine,
705 RenderLayer *layer,
706 const rcti *rect)
707{
708 using namespace blender::draw;
710 RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers");
711 return;
712 }
713
714 /* Setup */
716 const DRWContextState *draw_ctx = DRW_context_state_get();
717 Depsgraph *depsgraph = draw_ctx->depsgraph;
718
719 WORKBENCH_Data *ved = reinterpret_cast<WORKBENCH_Data *>(vedata);
720 if (ved->instance == nullptr) {
721 ved->instance = new workbench::Instance();
722 }
723
724 /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
726
727 /* Set the perspective, view and window matrix. */
728 float4x4 winmat, viewmat, viewinv;
729 RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
730 RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
731 viewmat = math::invert(viewinv);
732
733 /* Render */
734 /* TODO: Remove old draw manager calls. */
736 DRWView *view = DRW_view_create(viewmat.ptr(), winmat.ptr(), nullptr, nullptr, nullptr);
739
740 ved->instance->init(camera_ob);
741
742 draw::Manager &manager = *DRW_manager_get();
743 manager.begin_sync();
744
745 workbench_cache_init(vedata);
746 auto workbench_render_cache =
747 [](void *vedata, Object *ob, RenderEngine * /*engine*/, Depsgraph * /*depsgraph*/) {
748 workbench_cache_populate(vedata, ob);
749 };
750 DRW_render_object_iter(vedata, engine, depsgraph, workbench_render_cache);
752
753 manager.end_sync();
754
755 /* TODO: Remove old draw manager calls. */
757 DRW_curves_update();
758
760 ved->instance->draw_image_render(manager, dtxl.depth, dtxl.depth_in_front, dtxl.color, engine);
761
762 /* Write image */
763 const char *viewname = RE_GetActiveRenderView(engine->re);
764 write_render_color_output(layer, viewname, dfbl->default_fb, rect);
765 write_render_z_output(layer, viewname, dfbl->default_fb, rect, winmat);
766}
767
769 Scene *scene,
770 ViewLayer *view_layer)
771{
772 if (view_layer->passflag & SCE_PASS_COMBINED) {
773 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
774 }
775 if (view_layer->passflag & SCE_PASS_Z) {
776 RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT);
777 }
778}
779
780extern "C" {
781
783
785 /*next*/ nullptr,
786 /*prev*/ nullptr,
787 /*idname*/ N_("Workbench"),
788 /*vedata_size*/ &workbench_data_size,
789 /*engine_init*/ &workbench_engine_init,
790 /*engine_free*/ &workbench_engine_free,
791 /*instance_free*/ &workbench_instance_free,
792 /*cache_init*/ &workbench_cache_init,
793 /*cache_populate*/ &workbench_cache_populate,
794 /*cache_finish*/ &workbench_cache_finish,
795 /*draw_scene*/ &workbench_draw_scene,
796 /*view_update*/ &workbench_view_update,
797 /*id_update*/ &workbench_id_update,
798 /*render_to_image*/ &workbench_render_to_image,
799 /*store_metadata*/ nullptr,
800};
801
803 /*next*/ nullptr,
804 /*prev*/ nullptr,
805 /*idname*/ "BLENDER_WORKBENCH",
806 /*name*/ N_("Workbench"),
808 /*update*/ nullptr,
809 /*render*/ &DRW_render_to_image,
810 /*render_frame_finish*/ nullptr,
811 /*draw*/ nullptr,
812 /*bake*/ nullptr,
813 /*view_update*/ nullptr,
814 /*view_draw*/ nullptr,
815 /*update_script_node*/ nullptr,
816 /*update_render_passes*/ &workbench_render_update_passes,
817 /*draw_engine*/ &draw_engine_workbench,
818 /*rna_ext*/
819 {
820 /*data*/ nullptr,
821 /*srna*/ nullptr,
822 /*call*/ nullptr,
823 },
824};
825}
826
struct Material * BKE_material_default_empty(void)
struct Material * BKE_object_material_get_eval(struct Object *ob, short act)
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:50
#define ATTR_FALLTHROUGH
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:193
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:189
#define UNUSED_VARS(...)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ 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
char DRWViewportEmptyList
Definition DRW_render.hh:97
#define DRW_VIEWPORT_DATA_SIZE(ty)
void GPU_render_step()
eGPUBackendType GPU_backend_get_type()
bool GPU_framebuffer_check_valid(GPUFrameBuffer *framebuffer, char err_out[256])
#define GPU_ATTACHMENT_TEXTURE(_texture)
void GPU_framebuffer_clear_depth_stencil(GPUFrameBuffer *fb, float clear_depth, uint clear_stencil)
void GPU_framebuffer_read_depth(GPUFrameBuffer *framebuffer, int x, int y, int width, int height, eGPUDataFormat data_format, void *r_data)
#define GPU_ATTACHMENT_NONE
void GPU_framebuffer_multi_clear(GPUFrameBuffer *framebuffer, const float(*clear_colors)[4])
void GPU_framebuffer_bind(GPUFrameBuffer *framebuffer)
void GPU_framebuffer_read_color(GPUFrameBuffer *framebuffer, int x, int y, int width, int height, int channels, int slot, eGPUDataFormat data_format, void *r_data)
#define GPU_framebuffer_ensure_config(_fb,...)
void GPU_flush()
Definition gpu_state.cc:294
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
Contains defines and structs used throughout the imbuf module.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object instance
@ RE_INTERNAL
Definition RE_engine.h:47
@ RE_USE_STEREO_VIEWPORT
Definition RE_engine.h:53
@ RE_USE_GPU_CONTEXT
Definition RE_engine.h:54
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
int64_t size() const
void resize(const int64_t new_size)
void ensure(GPUAttachment depth=GPU_ATTACHMENT_NONE, GPUAttachment color1=GPU_ATTACHMENT_NONE, GPUAttachment color2=GPU_ATTACHMENT_NONE, GPUAttachment color3=GPU_ATTACHMENT_NONE, GPUAttachment color4=GPU_ATTACHMENT_NONE, GPUAttachment color5=GPU_ATTACHMENT_NONE, GPUAttachment color6=GPU_ATTACHMENT_NONE, GPUAttachment color7=GPU_ATTACHMENT_NONE, GPUAttachment color8=GPU_ATTACHMENT_NONE)
ResourceHandle resource_handle(const ObjectRef &ref, float inflate_bounds=0.0f)
void acquire(int2 extent, eGPUTextureFormat format, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL)
void wrap(GPUTexture *tex)
A running instance of the engine.
void setup_view(View &view, const SceneState &scene_state)
void draw(Manager &manager, View &view, const SceneState &scene_state, SceneResources &resources, GPUTexture *depth_in_front_tx)
void sync(const SceneState &scene_state, SceneResources &resources)
void sync(SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
void init(const SceneState &scene_state)
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 init(Object *camera_ob=nullptr)
TransparentDepthPass transparent_depth_ps
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)
void curves_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
GPUMaterial ** get_dummy_gpu_materials(int material_count)
void draw_mesh(ObjectRef &ob_ref, Material &material, gpu::Batch *batch, ResourceHandle handle, const MaterialTexture *texture=nullptr, bool show_missing_texture=false)
void object_sync(Manager &manager, ObjectRef &ob_ref)
void sculpt_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
void mesh_sync(ObjectRef &ob_ref, ResourceHandle handle, const ObjectState &object_state)
Vector< GPUMaterial * > dummy_gpu_materials
void hair_sync(Manager &manager, ObjectRef &ob_ref, ResourceHandle emitter_handle, const ObjectState &object_state, ParticleSystem *psys, ModifierData *md)
void point_cloud_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state)
void sync(const SceneState &scene_state, SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution, class ShadowPass *shadow_pass)
void draw(Manager &manager, SceneResources &resources)
void sync(SceneResources &resources)
void init(const SceneState &scene_state)
void init(const SceneState &scene_state, SceneResources &resources)
void object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandle handle, const bool has_transp_mat)
void draw(Manager &manager, View &view, SceneResources &resources)
void sync(const SceneState &scene_state, SceneResources &resources)
void sync(const SceneState &scene_state, SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
void sync(SceneResources &resources)
void object_sync_volume(Manager &manager, SceneResources &resources, const SceneState &scene_state, ObjectRef &ob_ref, float3 color)
void draw(Manager &manager, View &view, SceneResources &resources)
void object_sync_modifier(Manager &manager, SceneResources &resources, const SceneState &scene_state, ObjectRef &ob_ref, ModifierData *md)
local_group_size(16, 16) .push_constant(Type texture
const Depsgraph * depsgraph
#define fabsf(x)
blender::gpu::Batch * DRW_cache_object_surface_get(Object *ob)
blender::gpu::Batch * DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
blender::gpu::Batch * DRW_cache_mesh_surface_vertpaint_get(Object *ob)
blender::gpu::Batch ** DRW_cache_object_surface_material_get(Object *ob, GPUMaterial **gpumat_array, uint gpumat_array_len)
int DRW_cache_object_material_count_get(const Object *ob)
blender::gpu::Batch * DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
blender::gpu::Batch ** DRW_cache_mesh_surface_texpaint_get(Object *ob)
blender::draw::Manager * DRW_manager_get()
Object * DRW_object_get_dupli_parent(const Object *)
bool DRW_state_is_viewport_image_render()
DefaultFramebufferList * DRW_viewport_framebuffer_list_get()
void DRW_cache_restart()
const float * DRW_viewport_size_get()
bool DRW_object_is_renderable(const Object *ob)
void DRW_render_instance_buffer_finish()
int DRW_object_visibility_in_active_context(const Object *ob)
bool DRW_state_is_scene_render()
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
DefaultTextureList * DRW_viewport_texture_list_get()
void DRW_render_to_image(RenderEngine *engine, Depsgraph *depsgraph)
const DRWContextState * DRW_context_state_get()
DupliObject * DRW_object_get_dupli(const Object *)
void DRW_viewport_request_redraw()
void DRW_render_object_iter(void *vedata, RenderEngine *engine, Depsgraph *depsgraph, void(*callback)(void *vedata, Object *ob, RenderEngine *engine, Depsgraph *depsgraph))
const DRWView * DRW_view_default_get()
float DRW_view_near_distance_get(const DRWView *view)
bool DRW_view_is_persp_get(const DRWView *view)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_view_default_set(const DRWView *view)
DRWView * DRW_view_create(const float viewmat[4][4], const float winmat[4][4], const float(*culling_viewmat)[4], const float(*culling_winmat)[4], DRWCallVisibilityFn *visibility_fn)
void DRW_view_set_active(const DRWView *view)
#define SCULPT_DEBUG_DRAW
#define GPU_INFO_SIZE
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
struct @620::@622 batch
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:2846
Bounds< float3 > bounds_get(const Tree &pbvh)
Definition pbvh.cc:1480
Vector< SculptBatch > sculpt_batches_get(const Object *ob, SculptBatchFeature features)
@ SCULPT_BATCH_VERTEX_COLOR
CartesianBasis invert(const CartesianBasis &basis)
T midpoint(const T &a, const T &b)
VecBase< float, 4 > float4
vertex_in(0, Type::VEC2, "pos") .push_constant(Type ratio draw_mesh
RenderPass * RE_pass_find_by_name(RenderLayer *rl, const char *name, const char *viewname)
const char * RE_GetActiveRenderView(Render *re)
Depsgraph * depsgraph
GPUFrameBuffer * depth_only_fb
GPUFrameBuffer * color_only_fb
GPUFrameBuffer * default_fb
GPUTexture * depth_in_front
struct FluidDomainSettings * domain
Definition DNA_ID.h:413
ImBufFloatBuffer float_buffer
void * first
short base_flag
ListBase modifiers
ParticleSettings * part
struct Render * re
Definition RE_engine.h:141
struct ImBuf * ibuf
Definition RE_pipeline.h:68
DrawEngineType * engine_type
DRWViewportEmptyList * psl
DRWViewportEmptyList * stl
workbench::Instance * instance
char info[GPU_INFO_SIZE]
DRWViewportEmptyList * txl
DRWViewportEmptyList * fbl
const c_style_mat & ptr() const
DupliObject * dupli_object
void init(const SceneState &scene_state)
StorageVectorBuffer< Material > material_buf
void init(Object *camera_ob=nullptr)
float x
float y
int ymin
int xmin
#define N_(msgid)
static void workbench_draw_scene(void *vedata)
DrawEngineType draw_engine_workbench
static void workbench_cache_init(void *vedata)
RenderEngineType DRW_engine_viewport_workbench_type
static void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
static void workbench_id_update(void *vedata, ID *id)
static void workbench_instance_free(void *instance)
static void workbench_engine_init(void *vedata)
static void workbench_view_update(void *vedata)
static void write_render_z_output(RenderLayer *layer, const char *viewname, GPUFrameBuffer *fb, const rcti *rect, const float4x4 &winmat)
static void workbench_render_to_image(void *vedata, RenderEngine *engine, RenderLayer *layer, const rcti *rect)
static void workbench_cache_finish(void *vedata)
static void write_render_color_output(RenderLayer *layer, const char *viewname, GPUFrameBuffer *fb, const rcti *rect)
static bool workbench_render_framebuffers_init()
static const DrawEngineDataSize workbench_data_size
static void workbench_engine_free()
static void workbench_cache_populate(void *vedata, Object *object)