Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen Bakker <jbakker>2021-09-08 09:39:03 +0300
committerJeroen Bakker <jeroen@blender.org>2021-09-08 09:47:26 +0300
commit54f5c174a8cf480d934f3be8ecc85c76537ad148 (patch)
treeef5a0153d7d399e2a81ab5f1470e627279deb754 /source/blender/draw/engines/basic/basic_engine.c
parent8d40d61af093fcf528ce282b740eca119a5ee5d3 (diff)
Asset: Dropping Material assets on material slot under mouse cursor.
This patch allows dropping material assets from material slot under the mouse cursor. Before this change the material slot had to be hand-picked from the properties panel. For consistency it is chosen to do this in any shading mode as the tooltip shows what is exactly going to happen during release. The feature also works for other object types than Meshes as it uses the drawn surface on the GPU to detect the material slots. Performance of this patch has been tested with AMD GCN3.0 cards and are very responsive. Reviewed By: fclem, Severin Differential Revision: https://developer.blender.org/D12190
Diffstat (limited to 'source/blender/draw/engines/basic/basic_engine.c')
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index c120df7e897..87f5c6f5857 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -25,9 +25,12 @@
#include "DRW_render.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
+#include "BLI_alloca.h"
+
#include "DNA_particle_types.h"
#include "GPU_shader.h"
@@ -80,6 +83,7 @@ typedef struct BASIC_PrivateData {
DRWShadingGroup *depth_shgrp[2];
DRWShadingGroup *depth_shgrp_cull[2];
DRWShadingGroup *depth_hair_shgrp[2];
+ bool use_material_slot_selection;
} BASIC_PrivateData; /* Transient data */
/* Functions */
@@ -131,6 +135,8 @@ static void basic_cache_init(void *vedata)
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
}
+ stl->g_data->use_material_slot_selection = DRW_state_is_material_select();
+
/* Twice for normal and in front objects. */
for (int i = 0; i < 2; i++) {
DRWState clip_state = (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? DRW_STATE_CLIP_PLANES : 0;
@@ -155,6 +161,38 @@ static void basic_cache_init(void *vedata)
}
}
+/* TODO(fclem): DRW_cache_object_surface_material_get needs a refactor to allow passing NULL
+ * instead of gpumat_array. Avoiding all this boilerplate code. */
+static struct GPUBatch **basic_object_surface_material_get(Object *ob)
+{
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
+
+ return DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
+}
+
+static void basic_cache_populate_particles(void *vedata, Object *ob)
+{
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+ for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+ if (draw_as == PART_DRAW_PATH) {
+ struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
+ if (stl->g_data->use_material_slot_selection) {
+ const short material_slot = part->omat;
+ DRW_select_load_id(ob->runtime.select_id | (material_slot << 16));
+ }
+ DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
+ }
+ }
+}
+
static void basic_cache_populate(void *vedata, Object *ob)
{
BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
@@ -165,24 +203,13 @@ static void basic_cache_populate(void *vedata, Object *ob)
return;
}
- bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
-
const DRWContextState *draw_ctx = DRW_context_state_get();
if (ob != draw_ctx->object_edit) {
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
- if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
- continue;
- }
- ParticleSettings *part = psys->part;
- const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
- if (draw_as == PART_DRAW_PATH) {
- struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
- DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
- }
- }
+ basic_cache_populate_particles(vedata, ob);
}
/* Make flat object selectable in ortho view if wireframe is enabled. */
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
(draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
int flat_axis = 0;
@@ -211,9 +238,25 @@ static void basic_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt(shgrp, ob, false, false);
}
else {
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- DRW_shgroup_call(shgrp, geom, ob);
+ if (stl->g_data->use_material_slot_selection && BKE_object_supports_material_slots(ob)) {
+ struct GPUBatch **geoms = basic_object_surface_material_get(ob);
+ if (geoms) {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ if (geoms[i] == NULL) {
+ continue;
+ }
+ const short material_slot_select_id = i + 1;
+ DRW_select_load_id(ob->runtime.select_id | (material_slot_select_id << 16));
+ DRW_shgroup_call(shgrp, geoms[i], ob);
+ }
+ }
+ }
+ else {
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ DRW_shgroup_call(shgrp, geom, ob);
+ }
}
}
}