Lamp sunrays and shadow circles
authorClément Foucault <foucault.clem@gmail.com>
Thu, 2 Feb 2017 20:39:58 +0000 (21:39 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Thu, 2 Feb 2017 20:39:58 +0000 (21:39 +0100)
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache.h
source/blender/draw/intern/draw_mode_pass.c

index ac57a05dd142361ecb28fc2f9c45be9d90137b50..99456286536d50d96c0ad608b37b74a93db7cb19 100644 (file)
@@ -40,6 +40,7 @@
 #include "BLT_translation.h"
 
 #include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
 #include "DNA_material_types.h"
 #include "DNA_scene_types.h"
 
index b41c232847cafa69492adc0e73483d0450a8b38f..2f571ec7f3ce64ba0f7a1293c0d4b7d5d168fabe 100644 (file)
@@ -49,6 +49,7 @@ static struct DRWShapeCache{
        Batch *drw_empty_cone;
        Batch *drw_arrows;
        Batch *drw_lamp;
+       Batch *drw_lamp_sunrays;
 } SHC = {NULL};
 
 void DRW_shape_cache_free(void)
@@ -75,6 +76,8 @@ void DRW_shape_cache_free(void)
                Batch_discard_all(SHC.drw_arrows);
        if (SHC.drw_lamp)
                Batch_discard_all(SHC.drw_lamp);
+       if (SHC.drw_lamp_sunrays)
+               Batch_discard_all(SHC.drw_lamp_sunrays);
 }
 
 /* Quads */
@@ -439,6 +442,39 @@ Batch *DRW_cache_lamp_get(void)
 #undef NSEGMENTS
 }
 
+Batch *DRW_cache_lamp_sunrays_get(void)
+{
+       if (!SHC.drw_lamp_sunrays) {
+               float v[3], v1[3], v2[3];
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = add_attrib(&format, "pos", GL_FLOAT, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, 16);
+
+               for (int a = 0; a < 8; a++) {
+                       v[0] = sinf((2.0f * M_PI * a) / 8.0f);
+                       v[1] = cosf((2.0f * M_PI * a) / 8.0f);
+                       v[2] = 0.0f;
+
+                       mul_v3_v3fl(v1, v, 1.2f);
+                       mul_v3_v3fl(v2, v, 2.5f);
+
+                       setAttrib(vbo, pos_id, a * 2, v1);
+                       setAttrib(vbo, pos_id, a * 2 + 1, v2);
+               }
+
+               SHC.drw_lamp_sunrays = Batch_create(GL_LINES, vbo, NULL);
+       }
+       return SHC.drw_lamp_sunrays;
+}
+
+
 /* Object Center */
 Batch *DRW_cache_single_vert_get(void)
 {
index 881fc2b529be1fe4f8c7a67f93e96ab03cb027e0..c53f3d88af3c94c544048a69a8605576bdb33713 100644 (file)
@@ -46,6 +46,7 @@ struct Batch *DRW_cache_arrows_get(void);
 
 /* Lamps */
 struct Batch *DRW_cache_lamp_get(void);
+struct Batch *DRW_cache_lamp_sunrays_get(void);
 
 /* Meshes */
 struct Batch *DRW_cache_wire_overlay_get(struct Object *ob);
index 813fb2b38af026e64613240c02a82ca0a9336baa..391639e57dc6c6222be2b1d09e6dc7ea887c8309 100644 (file)
@@ -101,6 +101,12 @@ static DRWShadingGroup *lamp_groundline;
 static DRWShadingGroup *lamp_circle_wire;
 static DRWShadingGroup *lamp_circle_active;
 static DRWShadingGroup *lamp_circle_select;
+static DRWShadingGroup *lamp_circle_shadow_wire;
+static DRWShadingGroup *lamp_circle_shadow_active;
+static DRWShadingGroup *lamp_circle_shadow_select;
+static DRWShadingGroup *lamp_sunrays_wire;
+static DRWShadingGroup *lamp_sunrays_active;
+static DRWShadingGroup *lamp_sunrays_select;
 
 /* Helpers */
 static DRWShadingGroup *relationship_lines;
@@ -167,7 +173,7 @@ static DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float
        return grp;
 }
 
-static DRWShadingGroup *shgroup_lampcircle(DRWPass *pass, float color[4], float *size)
+static DRWShadingGroup *shgroup_lamp(DRWPass *pass, float color[4], float *size)
 {
        GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LAMP_COMMON);
 
@@ -189,7 +195,7 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
        static float colorWire[4], colorWireEdit[4];
        static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], colorGroupActive[4];
        static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
-       static float lampCenterSize, lampCircleRad, colorLampNoAlpha[4];
+       static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
 
        UI_GetThemeColor4fv(TH_WIRE, colorWire);
        UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit);
@@ -290,13 +296,20 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
                /* Lamps */
                lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize;
                lampCircleRad = U.pixelsize * 9.0f;
+               lampCircleShadowRad = lampCircleRad + U.pixelsize * 3.0f;
                /* TODO
                 * for now we create 3 times the same VBO with only lamp center coordinates
                 * but ideally we would only create it once */
                lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize);
-               lamp_circle_wire = shgroup_lampcircle(*non_meshes, colorLampNoAlpha, &lampCircleRad);
-               lamp_circle_active = shgroup_lampcircle(*non_meshes, colorActive, &lampCircleRad);
-               lamp_circle_select = shgroup_lampcircle(*non_meshes, colorSelect, &lampCircleRad);
+               lamp_circle_wire = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
+               lamp_circle_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
+               lamp_circle_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
+               lamp_circle_shadow_wire = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleShadowRad);
+               lamp_circle_shadow_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleShadowRad);
+               lamp_circle_shadow_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleShadowRad);
+               lamp_sunrays_wire = shgroup_lamp(*non_meshes, colorLampNoAlpha, &lampCircleRad);
+               lamp_sunrays_active = shgroup_lamp(*non_meshes, colorActive, &lampCircleRad);
+               lamp_sunrays_select = shgroup_lamp(*non_meshes, colorSelect, &lampCircleRad);
                lamp_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp);
                lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp);
 
@@ -503,6 +516,8 @@ static void DRW_draw_lamp(Object *ob)
 {
        struct Batch *geom = DRW_cache_single_vert_get();
        struct Batch *lamp = DRW_cache_lamp_get();
+       struct Batch *sunrays = DRW_cache_lamp_sunrays_get();
+       Lamp *la = ob->data;
 
        /* Don't draw the center if it's selected */
        if ((ob->base_flag & BASE_SELECTED) == 0) {
@@ -513,6 +528,27 @@ static void DRW_draw_lamp(Object *ob)
                DRW_shgroup_call_add(lamp_circle_select, lamp, ob->obmat);
        }
 
+       /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
+       if (la->type != LA_HEMI) {
+               if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
+                       if ((ob->base_flag & BASE_SELECTED) == 0) {
+                               DRW_shgroup_call_add(lamp_circle_shadow_wire, lamp, ob->obmat);
+                       }
+                       else {
+                               DRW_shgroup_call_add(lamp_circle_shadow_select, lamp, ob->obmat);
+                       }
+               }
+       }
+
+       if (la->type == LA_SUN) {
+               if ((ob->base_flag & BASE_SELECTED) == 0) {
+                       DRW_shgroup_call_add(lamp_sunrays_wire, sunrays, ob->obmat);
+               }
+               else {
+                       DRW_shgroup_call_add(lamp_sunrays_select, sunrays, ob->obmat);
+               }
+       }
+
        DRW_shgroup_call_add(lamp_groundline, geom, ob->obmat);
        DRW_shgroup_call_add(lamp_groundpoint, geom, ob->obmat);
 }