diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-04-03 20:01:10 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-04-03 22:52:42 +0300 |
commit | ccd8353d58d769d435822e7dac25d8fdf317d6df (patch) | |
tree | cb5f87027d838837d11e471bb009cd9ac65d438a | |
parent | 682c4dcd1ea43581b3a1f3b5df4afca59145d478 (diff) |
Object Engine: Fix multi user lamp data display bug.
Objects that were using the same lamp data were having the same display matrices.
This is fixed by allowing engine to store a memory block inside the object itself.
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 5 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/draw/DRW_engine.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 36 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 31 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_lamp_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 2 |
8 files changed, 69 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7250fd279c7..5f1e47e0f5a 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -119,6 +119,8 @@ #include "BKE_camera.h" #include "BKE_image.h" +#include "DRW_engine.h" + #ifdef WITH_MOD_FLUID #include "LBM_fluidsim.h" #endif @@ -443,6 +445,8 @@ void BKE_object_free(Object *ob) } GPU_lamp_free(ob); + DRW_object_engine_data_free(ob); + BKE_sculptsession_free(ob); BLI_freelistN(&ob->pc_ids); @@ -1177,6 +1181,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches) BLI_listbase_clear(&obn->gpulamp); BLI_listbase_clear(&obn->pc_ids); + BLI_listbase_clear(&obn->drawdata); obn->mpath = NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 2c9d1a47320..5f6663f4cc7 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5587,6 +5587,7 @@ static void direct_link_object(FileData *fd, Object *ob) ob->derivedDeform = NULL; ob->derivedFinal = NULL; BLI_listbase_clear(&ob->gpulamp); + BLI_listbase_clear(&ob->drawdata); link_list(fd, &ob->pc_ids); /* Runtime curve data */ diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 669f7a24908..87cfa8e8e3b 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -52,6 +52,8 @@ void DRW_engine_register(struct DrawEngineType *draw_engine_type); void DRW_draw_view(const struct bContext *C); +void DRW_object_engine_data_free(struct Object *ob); + /* This is here because GPUViewport needs it */ void DRW_pass_free(struct DRWPass *pass); diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 13b10011dec..dcef328e4ce 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -247,6 +247,9 @@ bool DRW_viewport_cache_is_dirty(void); struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void); struct DefaultTextureList *DRW_viewport_texture_list_get(void); +/* Objects */ +void **DRW_object_engine_data_get(Object *ob, DrawEngineType *det); + /* Settings */ bool DRW_is_object_renderable(struct Object *ob); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index a338c1f9f5f..a674c532310 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1377,6 +1377,42 @@ DefaultTextureList *DRW_viewport_texture_list_get(void) return GPU_viewport_texture_list_get(DST.viewport); } +/* **************************************** OBJECTS *************************************** */ + +typedef struct ObjectEngineData { + struct ObjectEngineData *next, *prev; + DrawEngineType *engine_type; + void *storage; +} ObjectEngineData; + +void **DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type) +{ + ObjectEngineData *oed; + + for (oed = ob->drawdata.first; oed; oed = oed->next) { + if (oed->engine_type == engine_type) { + return &oed->storage; + } + } + + oed = MEM_callocN(sizeof(ObjectEngineData), "ObjectEngineData"); + + BLI_addtail(&ob->drawdata, oed); + + return &oed->storage; +} + +void DRW_object_engine_data_free(Object *ob) +{ + for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) { + if (oed->storage) { + MEM_freeN(oed->storage); + } + } + + BLI_freelistN(&ob->drawdata); +} + /* **************************************** RENDERING ************************************** */ #define TIMER_FALLOFF 0.1f diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index e301c3e4e8a..5920889a453 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -683,6 +683,16 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl int theme_id = DRW_object_wire_theme_get(ob, sl, &color); static float zero = 0.0f; + float **la_mats = (float **)DRW_object_engine_data_get(ob, &draw_engine_object_type); + if (*la_mats == NULL) { + /* we need 2 matrices */ + *la_mats = MEM_mallocN(sizeof(float) * 16 * 2, "Lamp Object Mode Matrices"); + } + + float (*shapemat)[4], (*spotblendmat)[4]; + shapemat = (float (*)[4])*la_mats; + spotblendmat = (float (*)[4])*la_mats + 16; + /* Don't draw the center if it's selected or active */ if (theme_id == TH_GROUP) DRW_shgroup_dynamic_call_add(stl->g_data->lamp_center_group, ob->obmat[3]); @@ -704,7 +714,7 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl DRW_shgroup_dynamic_call_add(stl->g_data->lamp_distance, color, &zero, &la->dist, ob->obmat); } - copy_m4_m4(la->shapemat, ob->obmat); + copy_m4_m4(shapemat, ob->obmat); if (la->type == LA_SUN) { DRW_shgroup_dynamic_call_add(stl->g_data->lamp_sunrays, ob->obmat[3], color); @@ -718,42 +728,41 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl size[2] = cosf(la->spotsize * 0.5f) * la->dist; size_to_mat4(sizemat, size); - mul_m4_m4m4(la->spotconemat, ob->obmat, sizemat); + mul_m4_m4m4(shapemat, ob->obmat, sizemat); size[0] = size[1] = blend; size[2] = 1.0f; size_to_mat4(sizemat, size); translate_m4(sizemat, 0.0f, 0.0f, -1.0f); rotate_m4(sizemat, 'X', M_PI / 2.0f); - mul_m4_m4m4(la->spotblendmat, la->spotconemat, sizemat); + mul_m4_m4m4(spotblendmat, shapemat, sizemat); if (la->mode & LA_SQUARE) { - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_pyramid, color, &one, la->spotconemat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_pyramid, color, &one, shapemat); /* hide line if it is zero size or overlaps with outer border, * previously it adjusted to always to show it but that seems * confusing because it doesn't show the actual blend size */ if (blend != 0.0f && blend != 1.0f) { - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend_rect, color, &one, la->spotblendmat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend_rect, color, &one, spotblendmat); } } else { - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_cone, color, la->spotconemat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_cone, color, shapemat); /* hide line if it is zero size or overlaps with outer border, * previously it adjusted to always to show it but that seems * confusing because it doesn't show the actual blend size */ if (blend != 0.0f && blend != 1.0f) { - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend, color, &one, la->spotblendmat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend, color, &one, spotblendmat); } } - normalize_m4(la->shapemat); DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit, color, &la->clipsta, &la->clipend, ob->obmat); DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat); } else if (la->type == LA_HEMI) { static float hemisize = 2.0f; - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_hemi, color, &hemisize, la->shapemat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_hemi, color, &hemisize, shapemat); } else if (la->type == LA_AREA) { float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4]; @@ -761,10 +770,10 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl if (la->area_shape == LA_AREA_RECT) { size[1] = la->area_sizey / la->area_size; size_to_mat4(sizemat, size); - mul_m4_m4m4(la->shapemat, la->shapemat, sizemat); + mul_m4_m4m4(shapemat, shapemat, sizemat); } - DRW_shgroup_dynamic_call_add(stl->g_data->lamp_area, color, &la->area_size, la->shapemat); + DRW_shgroup_dynamic_call_add(stl->g_data->lamp_area, color, &la->area_size, shapemat); } /* Line and point going to the ground */ diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index 2393cbbf10d..a2e39f93875 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -106,10 +106,6 @@ typedef struct Lamp { short pr_texture, use_nodes; char pad6[4]; - float shapemat[4][4]; /* runtime, for display only */ - float spotconemat[4][4]; /* runtime, for display only */ - float spotblendmat[4][4]; /* runtime, for display only */ - /* preview */ struct PreviewImage *preview; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index a0ed163a4cb..71d05e41c43 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -304,6 +304,8 @@ typedef struct Object { struct PreviewImage *preview; struct IDProperty *base_collection_properties; /* used by depsgraph, flushed from base */ + + ListBase drawdata; /* runtime, for draw engine datas */ } Object; /* Warning, this is not used anymore because hooks are now modifiers */ |