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:
authorClément Foucault <foucault.clem@gmail.com>2017-04-03 20:01:10 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-04-03 22:52:42 +0300
commitccd8353d58d769d435822e7dac25d8fdf317d6df (patch)
treecb5f87027d838837d11e471bb009cd9ac65d438a
parent682c4dcd1ea43581b3a1f3b5df4afca59145d478 (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.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/draw/DRW_engine.h2
-rw-r--r--source/blender/draw/intern/DRW_render.h3
-rw-r--r--source/blender/draw/intern/draw_manager.c36
-rw-r--r--source/blender/draw/modes/object_mode.c31
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h4
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
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 */