From 92a2b444b034e41fd4997cb55ae59e5a82b319d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 2 Feb 2017 14:17:29 +0100 Subject: Added Lamp screen space visual --- source/blender/draw/intern/DRW_render.h | 2 ++ source/blender/draw/intern/draw_cache.c | 31 ++++++++++++++++++++++ source/blender/draw/intern/draw_cache.h | 3 +++ source/blender/draw/intern/draw_manager.c | 21 +++++++++++++++ source/blender/draw/intern/draw_mode_pass.c | 28 ++++++++++++++++++- source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/GPU_shader.h | 1 + source/blender/gpu/intern/gpu_shader.c | 6 ++++- .../gpu/shaders/gpu_shader_3D_lamp_vert.glsl | 24 +++++++++++++++++ 9 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 8bd3cabf8de..ac57a05dd14 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -196,6 +196,8 @@ typedef enum { void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes); void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type); float *DRW_viewport_size_get(void); +float *DRW_viewport_screenvecs_get(void); +float *DRW_viewport_pixelsize_get(void); bool DRW_viewport_is_persp_get(void); bool DRW_viewport_cache_is_dirty(void); diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index de171df511b..421d8ca54c4 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -48,6 +48,7 @@ static struct DRWShapeCache{ Batch *drw_empty_sphere; Batch *drw_empty_cone; Batch *drw_arrows; + Batch *drw_lamp; } SHC = {NULL}; /* Quads */ @@ -372,6 +373,36 @@ Batch *DRW_cache_arrows_get(void) return SHC.drw_arrows; } +/* Lamps */ +Batch *DRW_cache_lamp_get(void) +{ +#define NSEGMENTS 8 + if (!SHC.drw_lamp) { + float v[3] = {0.0f, 0.0f, 0.0f}; + + /* 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, NSEGMENTS); + + for (int a = 0; a < NSEGMENTS; a++) { + v[0] = sinf((2.0f * M_PI * a) / ((float)NSEGMENTS)); + v[1] = cosf((2.0f * M_PI * a) / ((float)NSEGMENTS)); + v[2] = 0.0f; + setAttrib(vbo, pos_id, a, v); + } + + SHC.drw_lamp = Batch_create(GL_LINE_LOOP, vbo, NULL); + } + return SHC.drw_lamp; +#undef NSEGMENTS +} + /* Object Center */ Batch *DRW_cache_single_vert_get(void) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index abe3ee7e771..b5d57e58a48 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -42,6 +42,9 @@ struct Batch *DRW_cache_empty_sphere_get(void); struct Batch *DRW_cache_empty_cone_get(void); struct Batch *DRW_cache_arrows_get(void); +/* Lamps */ +struct Batch *DRW_cache_lamp_get(void); + /* Meshes */ struct Batch *DRW_cache_wire_overlay_get(struct Object *ob); struct Batch *DRW_cache_wire_outline_get(struct Object *ob); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 3389c00c0d8..67d56099117 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -129,6 +129,8 @@ static struct DRWGlobalState{ ListBase bound_texs; int tex_bind_id; float size[2]; + float screenvecs[2][3]; + float pixsize; /* Current rendering context set by DRW_viewport_init */ const struct bContext *context; } DST = {NULL}; @@ -1051,6 +1053,16 @@ float *DRW_viewport_size_get(void) return &DST.size[0]; } +float *DRW_viewport_screenvecs_get(void) +{ + return &DST.screenvecs[0][0]; +} + +float *DRW_viewport_pixelsize_get(void) +{ + return &DST.pixsize; +} + void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes) { RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -1070,6 +1082,15 @@ void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void DST.current_fbl = (FramebufferList *)*buffers; DST.current_psl = (PassList *)*passes; + /* Refresh DST.screenvecs */ + copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]); + copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]); + normalize_v3(DST.screenvecs[0]); + normalize_v3(DST.screenvecs[1]); + + /* Refresh DST.pixelsize */ + DST.pixsize = rv3d->pixsize; + /* Save context for all later needs */ DST.context = C; } diff --git a/source/blender/draw/intern/draw_mode_pass.c b/source/blender/draw/intern/draw_mode_pass.c index bad791f1fc7..813fb2b38af 100644 --- a/source/blender/draw/intern/draw_mode_pass.c +++ b/source/blender/draw/intern/draw_mode_pass.c @@ -98,6 +98,9 @@ static DRWShadingGroup *arrows_group_active; static DRWShadingGroup *lamp_center; static DRWShadingGroup *lamp_groundpoint; static DRWShadingGroup *lamp_groundline; +static DRWShadingGroup *lamp_circle_wire; +static DRWShadingGroup *lamp_circle_active; +static DRWShadingGroup *lamp_circle_select; /* Helpers */ static DRWShadingGroup *relationship_lines; @@ -164,6 +167,20 @@ static DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float return grp; } +static DRWShadingGroup *shgroup_lampcircle(DRWPass *pass, float color[4], float *size) +{ + GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LAMP_COMMON); + + DRWShadingGroup *grp = DRW_shgroup_create(sh, pass); + DRW_shgroup_uniform_vec4(grp, "color", color, 1); + DRW_shgroup_uniform_float(grp, "size", size, 1); + DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1); + DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2); + DRW_shgroup_dyntype_set(grp, DRW_DYN_INSTANCE); + DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_3); + return grp; +} + /* This Function setup the passes needed for the mode rendering. * The passes are populated by the rendering engine using the DRW_shgroup_* functions. */ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **non_meshes, DRWPass **ob_center) @@ -172,7 +189,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, colorLampNoAlpha[4]; + static float lampCenterSize, lampCircleRad, colorLampNoAlpha[4]; UI_GetThemeColor4fv(TH_WIRE, colorWire); UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit); @@ -272,10 +289,14 @@ 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; /* 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_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp); lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp); @@ -481,10 +502,15 @@ void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob, static void DRW_draw_lamp(Object *ob) { struct Batch *geom = DRW_cache_single_vert_get(); + struct Batch *lamp = DRW_cache_lamp_get(); /* Don't draw the center if it's selected */ if ((ob->base_flag & BASE_SELECTED) == 0) { DRW_shgroup_call_add(lamp_center, geom, ob->obmat); + DRW_shgroup_call_add(lamp_circle_wire, lamp, ob->obmat); + } + else { + DRW_shgroup_call_add(lamp_circle_select, lamp, ob->obmat); } DRW_shgroup_call_add(lamp_groundline, geom, ob->obmat); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 08aab95d554..364e77123d9 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -156,6 +156,7 @@ data_to_c_simple(shaders/gpu_shader_3D_smooth_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_groundline_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC) +data_to_c_simple(shaders/gpu_shader_3D_lamp_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_point_uniform_color_smooth_frag.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index ad39f585d32..b36954dd010 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -134,6 +134,7 @@ typedef enum GPUBuiltinShader { /* lamp drawing */ GPU_SHADER_3D_GROUNDPOINT, GPU_SHADER_3D_GROUNDLINE, + GPU_SHADER_3D_LAMP_COMMON, GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */ } GPUBuiltinShader; diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index fb32477f401..0d6fd5f7b99 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -73,6 +73,7 @@ extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[]; extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[]; extern char datatoc_gpu_shader_3D_groundline_vert_glsl[]; extern char datatoc_gpu_shader_3D_groundline_geom_glsl[]; +extern char datatoc_gpu_shader_3D_lamp_vert_glsl[]; extern char datatoc_gpu_shader_point_uniform_color_frag_glsl[]; extern char datatoc_gpu_shader_point_uniform_color_smooth_frag_glsl[]; @@ -683,10 +684,13 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) [GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl }, [GPU_SHADER_3D_GROUNDPOINT] = { datatoc_gpu_shader_3D_groundpoint_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl }, - [GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_groundline_vert_glsl, + [GPU_SHADER_3D_GROUNDLINE] = { datatoc_gpu_shader_3D_groundline_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl, datatoc_gpu_shader_3D_groundline_geom_glsl }, + [GPU_SHADER_3D_LAMP_COMMON] = { datatoc_gpu_shader_3D_lamp_vert_glsl, + datatoc_gpu_shader_uniform_color_frag_glsl}, + [GPU_SHADER_2D_POINT_FIXED_SIZE_UNIFORM_COLOR] = { datatoc_gpu_shader_2D_vert_glsl, datatoc_gpu_shader_point_uniform_color_frag_glsl }, [GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR] = diff --git a/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl b/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl new file mode 100644 index 00000000000..8d091e9f432 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_3D_lamp_vert.glsl @@ -0,0 +1,24 @@ + +uniform mat4 ViewProjectionMatrix; +uniform vec3 screen_vecs[2]; +uniform float size; +uniform float pixel_size; + +in vec3 pos; +in mat4 InstanceModelMatrix; + +#define lamp_pos InstanceModelMatrix[3].xyz + +float mul_project_m4_v3_zfac(in vec3 co) +{ + return (ViewProjectionMatrix[0][3] * co.x) + + (ViewProjectionMatrix[1][3] * co.y) + + (ViewProjectionMatrix[2][3] * co.z) + ViewProjectionMatrix[3][3]; +} + +void main() +{ + float pix_size = mul_project_m4_v3_zfac(lamp_pos) * pixel_size; + vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y; + gl_Position = ViewProjectionMatrix * vec4(lamp_pos + screen_pos * size * pix_size, 1.0); +} -- cgit v1.2.3