Draw Manager: structural change
authorClément Foucault <foucault.clem@gmail.com>
Wed, 8 Mar 2017 19:00:09 +0000 (20:00 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Thu, 9 Mar 2017 00:30:26 +0000 (01:30 +0100)
All engines are now called by the draw manager. Engines are separate entities that cannot interfer with each others.
Also separated draw_mode_pass.c into the mode engines.

22 files changed:
source/blender/draw/CMakeLists.txt
source/blender/draw/DRW_engine.h
source/blender/draw/engines/clay/clay.c
source/blender/draw/engines/clay/clay.h
source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_armature.c
source/blender/draw/intern/draw_common.c [new file with mode: 0644]
source/blender/draw/intern/draw_common.h [moved from source/blender/draw/intern/draw_mode_pass.h with 52% similarity]
source/blender/draw/intern/draw_manager.c
source/blender/draw/intern/draw_mode_pass.c [deleted file]
source/blender/draw/modes/draw_mode_engines.h [moved from source/blender/draw/modes/object_mode.h with 73% similarity]
source/blender/draw/modes/edit_armature_mode.c
source/blender/draw/modes/edit_armature_mode.h [deleted file]
source/blender/draw/modes/edit_mesh_mode.c
source/blender/draw/modes/edit_mesh_mode.h [deleted file]
source/blender/draw/modes/object_mode.c
source/blender/editors/space_view3d/CMakeLists.txt
source/blender/editors/space_view3d/view3d_draw.c
source/blender/gpu/GPU_viewport.h
source/blender/gpu/intern/gpu_viewport.c
source/blender/render/extern/include/RE_engine.h
source/blender/render/intern/source/external_engine.c

index cb2681f..c04063d 100644 (file)
@@ -52,7 +52,7 @@ set(INC_SYS
 
 set(SRC
        intern/draw_manager.c
-       intern/draw_mode_pass.c
+       intern/draw_common.c
        intern/draw_cache.c
        intern/draw_view.c
        intern/draw_armature.c
@@ -62,13 +62,11 @@ set(SRC
        modes/object_mode.c
 
        intern/DRW_render.h
-       intern/draw_mode_pass.h
+       intern/draw_common.h
        intern/draw_cache.h
        intern/draw_view.h
        engines/clay/clay.h
-       modes/edit_armature_mode.h
-       modes/edit_mesh_mode.h
-       modes/object_mode.h
+       modes/draw_mode_engines.h
 
        ./DRW_engine.h
 )
index 05ecc73..e8dc472 100644 (file)
@@ -30,10 +30,27 @@ struct CollectionEngineSettings;
 struct DRWPass;
 struct Material;
 struct Scene;
+struct DrawEngineType;
+struct bContext;
+struct Object;
 
-void DRW_engines_init(void);
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+       struct GPUFrameBuffer *default_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+       struct GPUTexture *color;
+       struct GPUTexture *depth;
+} DefaultTextureList;
+
+void DRW_engines_register(void);
 void DRW_engines_free(void);
 
+void DRW_engine_register(struct DrawEngineType *draw_engine_type);
+
+void DRW_draw_view(const struct bContext *C);
+
 /* This is here because GPUViewport needs it */
 void DRW_pass_free(struct DRWPass *pass);
 
index cd19595..a91027c 100644 (file)
@@ -124,6 +124,15 @@ typedef struct CLAY_PassList {
        struct DRWPass *clay_pass;
 } CLAY_PassList;
 
+typedef struct CLAY_Data {
+       char engine_name[32];
+       CLAY_FramebufferList *fbl;
+       CLAY_TextureList *txl;
+       CLAY_PassList *psl;
+       CLAY_StorageList *stl;
+} CLAY_Data;
+
+
 //#define GTAO
 
 /* Functions */
@@ -262,20 +271,12 @@ RenderEngineSettings *CLAY_render_settings_create(void)
        return (RenderEngineSettings *)settings;
 }
 
-MaterialEngineSettings *CLAY_material_settings_create(void)
-{
-       MaterialEngineSettingsClay *settings = MEM_callocN(sizeof(MaterialEngineSettingsClay), "MaterialEngineSettingsClay");
-
-       clay_material_settings_init(settings);
-
-       return (MaterialEngineSettings *)settings;
-}
-
 static void CLAY_engine_init(void)
 {
-       CLAY_StorageList *stl = DRW_engine_storage_list_get();
-       CLAY_TextureList *txl = DRW_engine_texture_list_get();
-       CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_StorageList *stl = vedata->stl;
+       CLAY_TextureList *txl = vedata->txl;
+       CLAY_FramebufferList *fbl = vedata->fbl;
 
        /* Create Texture Array */
        if (!data.matcap_array) {
@@ -428,10 +429,11 @@ static void CLAY_engine_init(void)
 
 static DRWShadingGroup *CLAY_shgroup_create(DRWPass *pass, int *material_id)
 {
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_TextureList *txl = vedata->txl;
        const int depthloc = 0, matcaploc = 1, jitterloc = 2, sampleloc = 3;
 
        DRWShadingGroup *grp = DRW_shgroup_create(data.clay_sh, pass);
-       CLAY_TextureList *txl = DRW_engine_texture_list_get();
 
        DRW_shgroup_uniform_vec2(grp, "screenres", DRW_viewport_size_get(), 1);
        DRW_shgroup_uniform_buffer(grp, "depthtex", &txl->depth_dup, depthloc);
@@ -599,9 +601,9 @@ static DRWShadingGroup *depth_shgrp_cull;
 
 static void CLAY_cache_init(void)
 {
-       CLAY_PassList *psl = DRW_engine_pass_list_get();
-       CLAY_StorageList *stl = DRW_engine_storage_list_get();
-
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_PassList *psl = vedata->psl;
+       CLAY_StorageList *stl = vedata->stl;
 
        /* Depth Pass */
        {
@@ -622,100 +624,46 @@ static void CLAY_cache_init(void)
 
 static void CLAY_cache_populate(Object *ob)
 {
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
-       CLAY_StorageList *stl = DRW_engine_storage_list_get();
-       CLAY_PassList *psl = DRW_engine_pass_list_get();
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_PassList *psl = vedata->psl;
+       CLAY_StorageList *stl = vedata->stl;
+
        struct Batch *geom;
        DRWShadingGroup *clay_shgrp;
-       bool do_occlude_wire = false;
-       bool do_cull = false;
-       CollectionEngineSettings *ces_mode_ed, *ces_mode_ob;
-
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-               case CTX_MODE_EDIT_CURVE:
-               case CTX_MODE_EDIT_SURFACE:
-               case CTX_MODE_EDIT_TEXT:
-               case CTX_MODE_EDIT_ARMATURE:
-               case CTX_MODE_EDIT_METABALL:
-               case CTX_MODE_EDIT_LATTICE:
-               case CTX_MODE_POSE:
-               case CTX_MODE_SCULPT:
-               case CTX_MODE_PAINT_WEIGHT:
-               case CTX_MODE_PAINT_VERTEX:
-               case CTX_MODE_PAINT_TEXTURE:
-               case CTX_MODE_PARTICLE:
-                       ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
-                       do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
-                       break;
-               case CTX_MODE_OBJECT:
-                       ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
-                       do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
-                       break;
-       }
 
-       if (do_occlude_wire)
+       if (!DRW_is_object_renderable(ob))
                return;
 
-       switch (ob->type) {
-               case OB_MESH:
-                       geom = DRW_cache_surface_get(ob);
+       CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
+       bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
 
-                       /* Depth Prepass */
-                       DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
+       /* TODO all renderable */
+       if (ob->type == OB_MESH) {
+               geom = DRW_cache_surface_get(ob);
 
-                       /* Shading */
-                       clay_shgrp = CLAY_object_shgrp_get(ob, stl, psl);
-                       DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
-                       break;
+               /* Depth Prepass */
+               DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
+
+               /* Shading */
+               clay_shgrp = CLAY_object_shgrp_get(ob, stl, psl);
+               DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
        }
 }
 
 static void CLAY_cache_finish(void)
 {
-       CLAY_StorageList *stl = DRW_engine_storage_list_get();
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_StorageList *stl = vedata->stl;
 
        DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
 }
 
-static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
+static void CLAY_draw_scene(void)
 {
-       DRW_viewport_init(context);
-
-       /* This function may run for multiple viewports
-        * so get the current viewport buffers */
-       CLAY_PassList *psl = DRW_engine_pass_list_get();
-       CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
-
-       CLAY_engine_init();
-       DRW_mode_init();
-
-       /* TODO : tag to refresh by the deps graph */
-       /* ideally only refresh when objects are added/removed */
-       /* or render properties / materials change */
-       if (DRW_viewport_cache_is_dirty()) {
-
-               SceneLayer *sl = CTX_data_scene_layer(context);
-
-               CLAY_cache_init();
-               DRW_mode_cache_init();
-
-               DEG_OBJECT_ITER(sl, ob);
-               {
-                       CLAY_cache_populate(ob);
-                       DRW_mode_cache_populate(ob);
-               }
-               DEG_OBJECT_ITER_END
-
-               CLAY_cache_finish();
-               DRW_mode_cache_finish();
-       }
-
-       /* Start Drawing */
-       DRW_draw_background();
-
-       DRW_draw_callbacks_pre_scene();
+       CLAY_Data *vedata = DRW_viewport_engine_data_get("Clay");
+       CLAY_PassList *psl = vedata->psl;
+       CLAY_FramebufferList *fbl = vedata->fbl;
+       DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
 
        /* Pass 1 : Depth pre-pass */
        DRW_draw_pass(psl->depth_pass);
@@ -723,19 +671,10 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
 
        /* Pass 2 : Duplicate depth */
        /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
-       DRW_framebuffer_blit(fbl->default_fb, fbl->dupli_depth, true);
+       DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true);
 
        /* Pass 3 : Shading */
        DRW_draw_pass(psl->clay_pass);
-
-       /* Pass 4 : Overlays */
-       /* At this point all shaded geometry should have been rendered and their depth written */
-       DRW_draw_mode_overlays();
-
-       DRW_draw_callbacks_post_scene();
-
-       /* Always finish by this */
-       DRW_state_reset();
 }
 
 static void CLAY_collection_settings_create(RenderEngine *UNUSED(engine), CollectionEngineSettings *ces)
@@ -753,30 +692,39 @@ static void CLAY_collection_settings_create(RenderEngine *UNUSED(engine), Collec
        BKE_collection_engine_property_add_float(ces, "ssao_factor_edge", 1.0f);
 }
 
-void CLAY_engine_free(void)
+static void CLAY_engine_free(void)
 {
-       /* data.depth_sh Is builtin so it's automaticaly freed */
        if (data.clay_sh) {
                DRW_shader_free(data.clay_sh);
        }
-
        if (data.matcap_array) {
                DRW_texture_free(data.matcap_array);
        }
-
        if (data.jitter_tx) {
                DRW_texture_free(data.jitter_tx);
        }
-
        if (data.sampling_tx) {
                DRW_texture_free(data.sampling_tx);
        }
 }
 
+DrawEngineType draw_engine_clay_type = {
+       NULL, NULL,
+       N_("Clay"),
+       &CLAY_engine_init,
+       &CLAY_engine_free,
+       &CLAY_cache_init,
+       &CLAY_cache_populate,
+       &CLAY_cache_finish,
+       NULL,
+       &CLAY_draw_scene
+};
+
 RenderEngineType viewport_clay_type = {
        NULL, NULL,
        CLAY_ENGINE, N_("Clay"), RE_INTERNAL | RE_USE_OGL_PIPELINE,
-       NULL, NULL, NULL, NULL, &CLAY_view_draw, NULL, &CLAY_collection_settings_create,
+       NULL, NULL, NULL, NULL, NULL, NULL, &CLAY_collection_settings_create,
+       &draw_engine_clay_type,
        {NULL, NULL, NULL}
 };
 
index 34dd74b..1afe1ac 100644 (file)
@@ -31,6 +31,4 @@ extern RenderEngineType viewport_clay_type;
 struct RenderEngineSettings *CLAY_render_settings_create(void);
 struct MaterialEngineSettings *CLAY_material_settings_create(void);
 
-void CLAY_engine_free(void);
-
 #endif /* __CLAY_H__ */
index 77687eb..2751568 100644 (file)
@@ -44,7 +44,7 @@
 #include "DNA_material_types.h"
 #include "DNA_scene_types.h"
 
-#include "draw_mode_pass.h"
+#include "draw_common.h"
 #include "draw_cache.h"
 #include "draw_view.h"
 
@@ -59,12 +59,42 @@ struct GPUTexture;
 struct GPUUniformBuffer;
 struct Object;
 struct Batch;
+struct DefaultFramebufferList;
+struct DefaultTextureList;
 
 typedef struct DRWUniform DRWUniform;
 typedef struct DRWInterface DRWInterface;
 typedef struct DRWPass DRWPass;
 typedef struct DRWShadingGroup DRWShadingGroup;
 
+typedef struct DrawEngineType {
+       struct DrawEngineType *next, *prev;
+
+       char idname[32];
+
+       void (*engine_init)(void);
+       void (*engine_free)(void);
+
+       void (*cache_init)(void);
+       void (*cache_populate)(struct Object *ob);
+       void (*cache_finish)(void);
+
+       void (*draw_background)(void);
+       void (*draw_scene)(void);
+} DrawEngineType;
+
+#ifndef __DRW_ENGINE_H__
+/* Buffer and textures used by the viewport by default */
+typedef struct DefaultFramebufferList {
+       struct GPUFrameBuffer *default_fb;
+} DefaultFramebufferList;
+
+typedef struct DefaultTextureList {
+       struct GPUTexture *color;
+       struct GPUTexture *depth;
+} DefaultTextureList;
+#endif
+
 /* Textures */
 
 typedef enum {
@@ -199,27 +229,26 @@ typedef enum {
 
 void DRW_viewport_init(const bContext *C);
 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
+void DRW_viewport_engine_data_set(const char *engine_name, void *fbl, void *txl, void *psl,    void *stl);
+void *DRW_viewport_engine_data_get(const char *engine_name);
 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);
 
+struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void);
+struct DefaultTextureList     *DRW_viewport_texture_list_get(void);
+
 /* Settings */
+bool DRW_is_object_renderable(struct Object *ob);
 #ifndef __DRW_ENGINE_H__
 void *DRW_material_settings_get(Material *ma, const char *engine_name);
 void *DRW_render_settings_get(Scene *scene, const char *engine_name);
 #endif /* __DRW_ENGINE_H__ */
 
-/* Cache */
-void DRW_mode_init(void);
-void DRW_mode_cache_init(void);
-void DRW_mode_cache_populate(struct Object *ob);
-void DRW_mode_cache_finish(void);
-
 /* Draw commands */
 void DRW_draw_pass(DRWPass *pass);
-void DRW_draw_mode_overlays(void);
 
 void DRW_draw_callbacks_pre_scene(void);
 void DRW_draw_callbacks_post_scene(void);
@@ -229,12 +258,4 @@ void DRW_state_reset(void);
 /* Other */
 void DRW_get_dfdy_factors(float dfdyfac[2]);
 const struct bContext *DRW_get_context(void);
-void *DRW_engine_pass_list_get(void);
-void *DRW_engine_storage_list_get(void);
-void *DRW_engine_texture_list_get(void);
-void *DRW_engine_framebuffer_list_get(void);
-void *DRW_mode_pass_list_get(void);
-void *DRW_mode_storage_list_get(void);
-void *DRW_mode_texture_list_get(void);
-void *DRW_mode_framebuffer_list_get(void);
 #endif /* __DRW_RENDER_H__ */
index 24a183d..51c269a 100644 (file)
@@ -35,6 +35,8 @@
 #include "DNA_view3d_types.h"
 #include "DNA_object_types.h"
 
+#include "DRW_render.h"
+
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_dlrbTree.h"
 
 #include "UI_resources.h"
 
-#include "draw_mode_pass.h"
+#include "draw_common.h"
 
 #define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var))
 #define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag))
 
+static Object *current_armature;
+/* Reset when changing current_armature */
+static DRWShadingGroup *bone_octahedral_solid;
+static DRWShadingGroup *bone_octahedral_wire;
+static DRWShadingGroup *bone_point_solid;
+static DRWShadingGroup *bone_point_wire;
+static DRWShadingGroup *bone_axes;
+static DRWShadingGroup *relationship_lines;
+
+static DRWPass *bone_solid;
+static DRWPass *bone_wire;
+
+/* Octahedral */
+static void DRW_shgroup_bone_octahedral_solid(const float (*bone_mat)[4], const float color[4])
+{
+       if (bone_octahedral_solid == NULL) {
+               struct Batch *geom = DRW_cache_bone_octahedral_get();
+               bone_octahedral_solid = shgroup_instance_objspace_solid(bone_solid, geom, current_armature->obmat);
+       }
+
+       DRW_shgroup_dynamic_call_add(bone_octahedral_solid, bone_mat, color);
+}
+
+static void DRW_shgroup_bone_octahedral_wire(const float (*bone_mat)[4], const float color[4])
+{
+       if (bone_octahedral_wire == NULL) {
+               struct Batch *geom = DRW_cache_bone_octahedral_wire_outline_get();
+               bone_octahedral_wire = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
+       }
+
+       DRW_shgroup_dynamic_call_add(bone_octahedral_wire, bone_mat, color);
+}
+
+/* Head and tail sphere */
+static void DRW_shgroup_bone_point_solid(const float (*bone_mat)[4], const float color[4])
+{
+       if (bone_point_solid == NULL) {
+               struct Batch *geom = DRW_cache_bone_point_get();
+               bone_point_solid = shgroup_instance_objspace_solid(bone_solid, geom, current_armature->obmat);
+       }
+
+       DRW_shgroup_dynamic_call_add(bone_point_solid, bone_mat, color);
+}
+
+static void DRW_shgroup_bone_point_wire(const float (*bone_mat)[4], const float color[4])
+{
+       if (bone_point_wire == NULL) {
+               struct Batch *geom = DRW_cache_bone_point_wire_outline_get();
+               bone_point_wire = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
+       }
+
+       DRW_shgroup_dynamic_call_add(bone_point_wire, bone_mat, color);
+}
+
+/* Axes */
+static void DRW_shgroup_bone_axes(const float (*bone_mat)[4], const float color[4])
+{
+       if (bone_axes == NULL) {
+               struct Batch *geom = DRW_cache_bone_arrows_get();
+               bone_axes = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
+       }
+
+       DRW_shgroup_dynamic_call_add(bone_axes, bone_mat, color);
+}
+
+/* Relationship lines */
+static void UNUSED_FUNCTION(DRW_shgroup_bone_relationship_lines)(const float head[3], const float tail[3])
+{
+       DRW_shgroup_dynamic_call_add(relationship_lines, head);
+       DRW_shgroup_dynamic_call_add(relationship_lines, tail);
+}
+
 /* *************** Armature Drawing - Coloring API ***************************** */
 
 static float colorBoneSolid[4];
@@ -246,7 +320,7 @@ static void draw_bone_octahedral(EditBone *eBone, bPoseChannel *pchan, bArmature
        draw_points(eBone, pchan, arm);
 }
 
-void draw_armature_edit(Object *ob)
+static void draw_armature_edit(Object *ob)
 {
        EditBone *eBone;
        bArmature *arm = ob->data;
@@ -280,7 +354,7 @@ void draw_armature_edit(Object *ob)
 }
 
 /* if const_color is NULL do pose mode coloring */
-void draw_armature_pose(Object *ob, const float const_color[4])
+static void draw_armature_pose(Object *ob, const float const_color[4])
 {
        bArmature *arm = ob->data;
        bPoseChannel *pchan;
@@ -325,4 +399,45 @@ void draw_armature_pose(Object *ob, const float const_color[4])
                        }
                }
        }
+}
+
+/* this function set the object space to use
+ * for all subsequent DRW_shgroup_bone_*** calls */
+static void DRW_shgroup_armature(
+    Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWShadingGroup *shgrp_relationship_lines)
+{
+       current_armature = ob;
+       bone_octahedral_solid = NULL;
+       bone_octahedral_wire = NULL;
+       bone_point_solid = NULL;
+       bone_point_wire = NULL;
+       bone_axes = NULL;
+
+       bone_solid = pass_bone_solid;
+       bone_wire = pass_bone_wire;
+       relationship_lines = shgrp_relationship_lines;
+}
+
+void DRW_shgroup_armature_object(
+    Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWShadingGroup *shgrp_relationship_lines)
+{
+       float *color;
+       DRW_object_wire_theme_get(ob, &color);
+
+       DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, shgrp_relationship_lines);
+       draw_armature_pose(ob, color);
+}
+
+void DRW_shgroup_armature_pose(
+    Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWShadingGroup *shgrp_relationship_lines)
+{
+       DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, shgrp_relationship_lines);
+       draw_armature_pose(ob, NULL);
+}
+
+void DRW_shgroup_armature_edit(
+    Object *ob, DRWPass *pass_bone_solid, DRWPass *pass_bone_wire, DRWShadingGroup *shgrp_relationship_lines)
+{
+       DRW_shgroup_armature(ob, pass_bone_solid, pass_bone_wire, shgrp_relationship_lines);
+       draw_armature_edit(ob);
 }
\ No newline at end of file
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
new file mode 100644 (file)
index 0000000..b9c73e8
--- /dev/null
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file blender/draw/intern/draw_common.c
+ *  \ingroup draw
+ */
+
+#include "DRW_render.h"
+
+#include "GPU_shader.h"
+
+#include "UI_resources.h"
+
+#include "BKE_global.h"
+
+#include "draw_common.h"
+
+/* Colors & Constant */
+GlobalsUboStorage ts;
+struct GPUUniformBuffer *globals_ubo = NULL;
+
+void DRW_globals_update(void)
+{
+       UI_GetThemeColor4fv(TH_WIRE, ts.colorWire);
+       UI_GetThemeColor4fv(TH_WIRE_EDIT, ts.colorWireEdit);
+       UI_GetThemeColor4fv(TH_ACTIVE, ts.colorActive);
+       UI_GetThemeColor4fv(TH_SELECT, ts.colorSelect);
+       UI_GetThemeColor4fv(TH_TRANSFORM, ts.colorTransform);
+       UI_GetThemeColor4fv(TH_GROUP_ACTIVE, ts.colorGroupActive);
+       UI_GetThemeColor4fv(TH_GROUP, ts.colorGroup);
+       UI_GetThemeColor4fv(TH_LAMP, ts.colorLamp);
+       UI_GetThemeColor4fv(TH_SPEAKER, ts.colorSpeaker);
+       UI_GetThemeColor4fv(TH_CAMERA, ts.colorCamera);
+       UI_GetThemeColor4fv(TH_EMPTY, ts.colorEmpty);
+       UI_GetThemeColor4fv(TH_VERTEX, ts.colorVertex);
+       UI_GetThemeColor4fv(TH_VERTEX_SELECT, ts.colorVertexSelect);
+       UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, ts.colorEditMeshActive);
+       UI_GetThemeColor4fv(TH_EDGE_SELECT, ts.colorEdgeSelect);
+       UI_GetThemeColor4fv(TH_EDGE_SEAM, ts.colorEdgeSeam);
+       UI_GetThemeColor4fv(TH_EDGE_SHARP, ts.colorEdgeSharp);
+       UI_GetThemeColor4fv(TH_EDGE_CREASE, ts.colorEdgeCrease);
+       UI_GetThemeColor4fv(TH_EDGE_BEVEL, ts.colorEdgeBWeight);
+       UI_GetThemeColor4fv(TH_EDGE_FACESEL, ts.colorEdgeFaceSelect);
+       UI_GetThemeColor4fv(TH_FACE, ts.colorFace);
+       UI_GetThemeColor4fv(TH_FACE_SELECT, ts.colorFaceSelect);
+       UI_GetThemeColor4fv(TH_NORMAL, ts.colorNormal);
+       UI_GetThemeColor4fv(TH_VNORMAL, ts.colorVNormal);
+       UI_GetThemeColor4fv(TH_LNORMAL, ts.colorLNormal);
+       UI_GetThemeColor4fv(TH_FACE_DOT, ts.colorFaceDot);
+
+       UI_GetThemeColorShadeAlpha4fv(TH_TRANSFORM, 0, -80, ts.colorDeselect);
+       UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, ts.colorOutline);
+       UI_GetThemeColorShadeAlpha4fv(TH_LAMP, 0, 255, ts.colorLampNoAlpha);
+
+       ts.sizeLampCenter = (U.obcenter_dia + 1.5f) * U.pixelsize;
+       ts.sizeLampCircle = U.pixelsize * 9.0f;
+       ts.sizeLampCircleShadow = ts.sizeLampCircle + U.pixelsize * 3.0f;
+
+       /* M_SQRT2 to be at least the same size of the old square */
+       ts.sizeVertex = UI_GetThemeValuef(TH_VERTEX_SIZE) * M_SQRT2 / 2.0f;
+       ts.sizeFaceDot = UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2;
+       ts.sizeEdge = 1.0f / 2.0f; /* TODO Theme */
+       ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * M_SQRT1_2);
+       ts.sizeNormal = 1.0f; /* TODO compute */
+
+       /* TODO Waiting for notifiers to invalidate cache */
+       if (globals_ubo) {
+               DRW_uniformbuffer_free(globals_ubo);
+       }
+
+       globals_ubo = DRW_uniformbuffer_create(sizeof(GlobalsUboStorage), &ts);
+}
+
+/* ********************************* SHGROUP ************************************* */
+
+DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+
+       DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
+       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4], float *size)
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+
+       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+       DRW_shgroup_uniform_float(grp, "size", size, 1);
+       DRW_shgroup_state_set(grp, DRW_STATE_POINT);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float color[4])
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
+
+       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4])
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
+
+       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
+       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
+       DRW_shgroup_state_set(grp, DRW_STATE_POINT);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Batch *geom, float *size)
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+       DRW_shgroup_attrib_float(grp, "world_pos", 3);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       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_state_set(grp, DRW_STATE_STIPPLE_3);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_instance_objspace_solid(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+       static float light[3] = {0.0f, 0.0f, 1.0f};
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_attrib_float(grp, "color", 4);
+       DRW_shgroup_uniform_mat4(grp, "ModelMatrix", (float *)obmat);
+       DRW_shgroup_uniform_vec3(grp, "light", light, 1);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_attrib_float(grp, "color", 4);
+       DRW_shgroup_uniform_mat4(grp, "ModelMatrix", (float *)obmat);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "size", 1);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "size", 1);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "corners", 8);
+       DRW_shgroup_attrib_float(grp, "depth", 1);
+       DRW_shgroup_attrib_float(grp, "tria", 4);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES);
+       static float point_size = 4.0f;
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "start", 1);
+       DRW_shgroup_attrib_float(grp, "end", 1);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
+
+       return grp;
+}
+
+DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR);
+       static bool True = true;
+       static bool False = false;
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
+       DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
+       DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
+
+       return grp;
+}
+
+/* ******************************************** WIRES *********************************************** */
+
+/* TODO FINISH */
+/* Get the wire color theme_id of an object based on it's state
+ * **color is a way to get a pointer to the static color var associated */
+int DRW_object_wire_theme_get(Object *ob, float **color)
+{
+       const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
+       /* confusing logic here, there are 2 methods of setting the color
+        * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
+        *
+        * note: no theme yet for 'colindex' */
+       int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
+
+       if (//(scene->obedit == NULL) &&
+           ((G.moving & G_TRANSFORM_OBJ) != 0) &&
+           ((ob->base_flag & BASE_SELECTED) != 0))
+       {
+               theme_id = TH_TRANSFORM;
+       }
+       else {
+               /* Sets the 'theme_id' or fallback to wire */
+               if ((ob->flag & OB_FROMGROUP) != 0) {
+                       if ((ob->base_flag & BASE_SELECTED) != 0) {
+                               /* uses darker active color for non-active + selected */
+                               theme_id = TH_GROUP_ACTIVE;
+
+                               // if (scene->basact != base) {
+                               //      theme_shade = -16;
+                               // }
+                       }
+                       else {
+                               theme_id = TH_GROUP;
+                       }
+               }
+               else {
+                       if ((ob->base_flag & BASE_SELECTED) != 0) {
+                               theme_id = //scene->basact == base ? TH_ACTIVE :
+                               TH_SELECT;
+                       }
+                       else {
+                               if (ob->type == OB_LAMP) theme_id = TH_LAMP;
+                               else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
+                               else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
+                               else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
+                               /* fallback to TH_WIRE */
+                       }
+               }
+       }
+
+       if (color != NULL) {
+               switch (theme_id) {
+                       case TH_WIRE_EDIT:    *color = ts.colorTransform; break;
+                       case TH_ACTIVE:       *color = ts.colorActive; break;
+                       case TH_SELECT:       *color = ts.colorSelect; break;
+                       case TH_GROUP:        *color = ts.colorGroup; break;
+                       case TH_GROUP_ACTIVE: *color = ts.colorGroupActive; break;
+                       case TH_TRANSFORM:    *color = ts.colorTransform; break;
+                       case OB_SPEAKER:      *color = ts.colorSpeaker; break;
+                       case OB_CAMERA:       *color = ts.colorCamera; break;
+                       case OB_EMPTY:        *color = ts.colorEmpty; break;
+                       case OB_LAMP:         *color = ts.colorLamp; break;
+                       default:              *color = ts.colorWire; break;
+               }
+       }
+
+       return theme_id;
+}
similarity index 52%
rename from source/blender/draw/intern/draw_mode_pass.h
rename to source/blender/draw/intern/draw_common.h
index fd66120..400a7e7 100644 (file)
  *
  */
 
-/** \file draw_mode_pass.h
+/** \file draw_common.h
  *  \ingroup draw
  */
 
-#ifndef __DRAW_MODE_PASS_H__
-#define __DRAW_MODE_PASS_H__
+#ifndef __DRAW_COMMON__
+#define __DRAW_COMMON__
 
 struct DRWPass;
+struct DRWShadingGroup;
 struct Batch;
 struct Object;
 
@@ -72,37 +73,34 @@ typedef struct GlobalsUboStorage {
 } GlobalsUboStorage;
 /* Keep in sync with globalsBlock in shaders */
 
-void DRW_update_global_values(void);
+void DRW_globals_update(void);
 
-void DRW_mode_passes_setup(struct DRWPass **psl_wire_overlay,
-                           struct DRWPass **psl_wire_overlay_hidden_wire,
-                           struct DRWPass **psl_wire_outline,
-                           struct DRWPass **psl_non_meshes,
-                           struct DRWPass **psl_ob_center,
-                           struct DRWPass **psl_bone_solid,
-                           struct DRWPass **psl_bone_wire);
+struct DRWShadingGroup *shgroup_dynlines_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_dynpoints_uniform_color(struct DRWPass *pass, float color[4], float *size);
+struct DRWShadingGroup *shgroup_groundlines_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, float color[4]);
+struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Batch *geom, float *size);
+struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Batch *geom);
 
-void DRW_shgroup_wire_outline(struct Object *ob, const bool do_front, const bool do_back, const bool do_outline);
-void DRW_shgroup_lamp(struct Object *ob);
-void DRW_shgroup_camera(struct Object *ob);
-void DRW_shgroup_empty(struct Object *ob);
-void DRW_shgroup_speaker(struct Object *ob);
-void DRW_shgroup_relationship_lines(struct Object *ob);
-void DRW_shgroup_object_center(struct Object *ob);
+int DRW_object_wire_theme_get(struct Object *ob, float **color);
 
-void DRW_shgroup_armature_object(struct Object *ob);
-void DRW_shgroup_armature_edit(struct Object *ob);
-void DRW_shgroup_armature_pose(struct Object *ob);
+/* draw_armature.c */
+void DRW_shgroup_armature_object(
+    struct Object *ob, struct DRWPass *pass_bone_solid,
+    struct DRWPass *pass_bone_wire, struct DRWShadingGroup *shgrp_relationship_lines);
 
-void DRW_shgroup_bone_octahedral_solid(const float (*arm_mat)[4], const float color[4]);
-void DRW_shgroup_bone_octahedral_wire(const float (*arm_mat)[4], const float color[4]);
-void DRW_shgroup_bone_point_solid(const float (*arm_mat)[4], const float color[4]);
-void DRW_shgroup_bone_point_wire(const float (*arm_mat)[4], const float color[4]);
-void DRW_shgroup_bone_relationship_lines(const float head[3], const float tail[3]);
-void DRW_shgroup_bone_axes(const float (*arm_mat)[4], const float color[4]);
+void DRW_shgroup_armature_pose(
+    struct Object *ob, struct DRWPass *pass_bone_solid,
+    struct DRWPass *pass_bone_wire, struct DRWShadingGroup *shgrp_relationship_lines);
 
-/* draw_armature.c */
-void draw_armature_edit(struct Object *ob);
-void draw_armature_pose(struct Object *ob, const float const_color[4]);
+void DRW_shgroup_armature_edit(
+    struct Object *ob, struct DRWPass *pass_bone_solid,
+    struct DRWPass *pass_bone_wire, struct DRWShadingGroup *shgrp_relationship_lines);
 
-#endif /* __DRAW_MODE_PASS_H__ */
\ No newline at end of file
+#endif /* __DRAW_COMMON__ */
\ No newline at end of file
index 381414f..54e5fa5 100644 (file)
@@ -39,6 +39,7 @@
 #include "DRW_render.h"
 
 #include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
 
 #include "ED_space_api.h"
 
@@ -55,9 +56,7 @@
 
 #include "UI_resources.h"
 
-#include "object_mode.h"
-#include "edit_armature_mode.h"
-#include "edit_mesh_mode.h"
+#include "draw_mode_engines.h"
 #include "clay.h"
 
 #define MAX_ATTRIB_NAME 32
@@ -163,21 +162,25 @@ enum {
 
 /* Render State */
 static struct DRWGlobalState {
+       /* Rendering state */
        GPUShader *shader;
-       struct GPUFrameBuffer *default_framebuffer;
-       FramebufferList *fbl, *fbl_mode;
-       TextureList *txl, *txl_mode;
-       PassList *psl, *psl_mode;
-       StorageList *stl, *stl_mode;
        ListBase bound_texs;
        int tex_bind_id;
+
+       /* Per viewport */
+       GPUViewport *viewport;
+       struct GPUFrameBuffer *default_framebuffer;
        float size[2];
        float screenvecs[2][3];
        float pixsize;
-       /* Current rendering context set by DRW_viewport_init */
+
+       /* Current rendering context */
        const struct bContext *context;
+       ListBase enabled_engines; /* RenderEngineType */
 } DST = {NULL};
 
+ListBase DRW_engines = {NULL, NULL};
+
 /* ***************************************** TEXTURES ******************************************/
 static void drw_texture_get_format(DRWTextureFormat format, GPUTextureFormat *data_type, int *channels)
 {
@@ -1067,28 +1070,6 @@ void DRW_state_reset(void)
        set_state(state);
 }
 
-void DRW_draw_mode_overlays(void)
-{
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
-
-       DRW_draw_grid();
-
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-                       EDIT_MESH_draw();
-                       break;
-               case CTX_MODE_EDIT_ARMATURE:
-                       EDIT_ARMATURE_draw();
-                       break;
-               case CTX_MODE_OBJECT:
-                       OBJECT_draw();
-                       break;
-       }
-
-       DRW_draw_manipulator();
-       DRW_draw_region_info();
-}
 #else
 void DRW_draw_pass(DRWPass *UNUSED(pass))
 {
@@ -1096,79 +1077,26 @@ void DRW_draw_pass(DRWPass *UNUSED(pass))
 
 #endif
 
-/* ******************************************* Mode Engine Cache ****************************************** */
+/* ****************************************** Settings ******************************************/
 
-void DRW_mode_init(void)
+bool DRW_is_object_renderable(Object *ob)
 {
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
-
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-                       EDIT_MESH_init();
-                       break;
-               case CTX_MODE_EDIT_ARMATURE:
-                       break;
-               case CTX_MODE_OBJECT:
-                       break;
-       }
-}
+       Scene *scene = CTX_data_scene(DST.context);
+       Object *obedit = scene->obedit;
 
-void DRW_mode_cache_init(void)
-{
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
+       if (ob->type == OB_MESH) {
+               if (ob == obedit) {
+                       CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
+                       bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
 
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-                       EDIT_MESH_cache_init();
-                       break;
-               case CTX_MODE_EDIT_ARMATURE:
-                       EDIT_ARMATURE_cache_init();
-                       break;
-               case CTX_MODE_OBJECT:
-                       OBJECT_cache_init();
-                       break;
-       }
-}
-
-void DRW_mode_cache_populate(Object *ob)
-{
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
-
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-                       EDIT_MESH_cache_populate(ob);
-                       break;
-               case CTX_MODE_EDIT_ARMATURE:
-                       EDIT_ARMATURE_cache_populate(ob);
-                       break;
-               case CTX_MODE_OBJECT:
-                       OBJECT_cache_populate(ob);
-                       break;
+                       if (do_occlude_wire)
+                               return false;
+               }
        }
-}
-
-void DRW_mode_cache_finish(void)
-{
-       const bContext *C = DRW_get_context();
-       int mode = CTX_data_mode_enum(C);
 
-       switch (mode) {
-               case CTX_MODE_EDIT_MESH:
-                       EDIT_MESH_cache_finish();
-                       break;
-               case CTX_MODE_EDIT_ARMATURE:
-                       EDIT_ARMATURE_cache_finish();
-                       break;
-               case CTX_MODE_OBJECT:
-                       OBJECT_cache_finish();
-                       break;
-       }
+       return true;
 }
 
-/* ****************************************** Settings ******************************************/
 void *DRW_material_settings_get(Material *ma, const char *engine_name)
 {
        MaterialEngineSettings *ms = NULL;
@@ -1184,7 +1112,8 @@ void *DRW_material_settings_get(Material *ma, const char *engine_name)
 
                /* TODO make render_settings_create a polymorphic function */
                if (STREQ(engine_name, RE_engine_id_BLENDER_CLAY)) {
-                       ms->data = CLAY_material_settings_create();
+                       /* No material support */
+                       BLI_assert(false);
                }
                else {
                        /* No engine matched */
@@ -1309,6 +1238,15 @@ void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer
 }
 
 /* ****************************************** Viewport ******************************************/
+void *DRW_viewport_engine_data_get(const char *engine_name)
+{
+       void *data = GPU_viewport_engine_data_get(DST.viewport, engine_name);
+
+       if (data == NULL) {
+               data = GPU_viewport_engine_data_create(DST.viewport, engine_name);
+       }
+       return data;
+}
 
 float *DRW_viewport_size_get(void)
 {
@@ -1325,20 +1263,21 @@ float *DRW_viewport_pixelsize_get(void)
        return &DST.pixsize;
 }
 
-void DRW_viewport_init(const bContext *C)
+/* It also stores viewport variable to an immutable place: DST
+ * This is because a cache uniform only store reference
+ * to its value. And we don't want to invalidate the cache
+ * if this value change per viewport */
+static void DRW_viewport_var_init(const bContext *C)
 {
        RegionView3D *rv3d = CTX_wm_region_view3d(C);
-       GPUViewport *viewport = rv3d->viewport;
-
-       GPU_viewport_get_engine_data(viewport, &DST.fbl, &DST.txl, &DST.psl, &DST.stl);
-       GPU_viewport_get_mode_data(viewport, &DST.fbl_mode, &DST.txl_mode, &DST.psl_mode, &DST.stl_mode);
 
        /* Refresh DST.size */
-       DefaultTextureList *txl = (DefaultTextureList *)DST.txl;
-       DST.size[0] = (float)GPU_texture_width(txl->color);
-       DST.size[1] = (float)GPU_texture_height(txl->color);
+       int size[2];
+       GPU_viewport_size_get(DST.viewport, size);
+       DST.size[0] = size[0];
+       DST.size[1] = size[1];
 
-       DefaultFramebufferList *fbl = (DefaultFramebufferList *)DST.fbl;
+       DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
        DST.default_framebuffer = fbl->default_fb;
 
        /* Refresh DST.screenvecs */
@@ -1352,8 +1291,6 @@ void DRW_viewport_init(const bContext *C)
 
        /* Save context for all later needs */
        DST.context = C;
-
-       DRW_update_global_values();
 }
 
 void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
@@ -1374,77 +1311,251 @@ bool DRW_viewport_is_persp_get(void)
        return rv3d->is_persp;
 }
 
-bool DRW_viewport_cache_is_dirty(void)
+DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void)
 {
-       /* TODO Use a dirty flag */
-       return (DST.psl->passes[0] == NULL);
+       return GPU_viewport_framebuffer_list_get(DST.viewport);
 }
 
-/* ****************************************** OTHER ***************************************** */
+DefaultTextureList *DRW_viewport_texture_list_get(void)
+{
+       return GPU_viewport_texture_list_get(DST.viewport);
+}
 
-const bContext *DRW_get_context(void)
+/* **************************************** RENDERING ************************************** */
+
+static void DRW_engines_init(void)
 {
-       return DST.context;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->engine_init) {
+                       engine->engine_init();
+               }
+       }
 }
 
-void *DRW_engine_pass_list_get(void)
+static void DRW_engines_cache_init(void)
 {
-       return DST.psl;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->cache_init) {
+                       engine->cache_init();
+               }
+       }
 }
 
-void *DRW_engine_storage_list_get(void)
+static void DRW_engines_cache_populate(Object *ob)
 {
-       return DST.stl;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->cache_populate) {
+                       engine->cache_populate(ob);
+               }
+       }
 }
 
-void *DRW_engine_texture_list_get(void)
+static void DRW_engines_cache_finish(void)
 {
-       return DST.txl;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->cache_finish) {
+                       engine->cache_finish();
+               }
+       }
 }
 
-void *DRW_engine_framebuffer_list_get(void)
+static void DRW_engines_draw_background(void)
 {
-       return DST.fbl;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->draw_background) {
+                       engine->draw_background();
+                       return;
+               }
+       }
+
+       /* No draw_background found, doing default background */
+       DRW_draw_background();
 }
 
-void *DRW_mode_pass_list_get(void)
+static void DRW_engines_draw_scene(void)
 {
-       return DST.psl_mode;
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               if (engine->draw_scene) {
+                       engine->draw_scene();
+               }
+       }
 }
 
-void *DRW_mode_storage_list_get(void)
+static void use_drw_engine(DrawEngineType *engine)
 {
-       return DST.stl_mode;
+       LinkData *ld = MEM_callocN(sizeof(LinkData), "enabled engine link data");
+       ld->data = engine;
+       BLI_addtail(&DST.enabled_engines, ld);
 }
 
-void *DRW_mode_texture_list_get(void)
+/* TODO revisit this when proper layering is implemented */
+/* Gather all draw engines needed and store them in DST.enabled_engines
+ * That also define the rendering order of engines */
+static void DRW_engines_enable(const bContext *C)
 {
-       return DST.txl_mode;
+       /* TODO layers */
+       Scene *scene = CTX_data_scene(C);
+       RenderEngineType *type = RE_engines_find(scene->r.engine);
+       use_drw_engine(type->draw_engine);
+
+       /* TODO Refine the folowing logic based on objects states
+        * not on global state.
+        * Order is important */
+       use_drw_engine(&draw_engine_object_type);
+
+       switch (CTX_data_mode_enum(C)) {
+               case CTX_MODE_EDIT_MESH:
+                       use_drw_engine(&draw_engine_edit_mesh_type);
+                       break;
+               case CTX_MODE_EDIT_CURVE:
+                       break;
+               case CTX_MODE_EDIT_SURFACE:
+                       break;
+               case CTX_MODE_EDIT_TEXT:
+                       break;
+               case CTX_MODE_EDIT_ARMATURE:
+                       use_drw_engine(&draw_engine_edit_armature_type);
+                       break;
+               case CTX_MODE_EDIT_METABALL:
+                       break;
+               case CTX_MODE_EDIT_LATTICE:
+                       break;
+               case CTX_MODE_POSE:
+                       break;
+               case CTX_MODE_SCULPT:
+                       break;
+               case CTX_MODE_PAINT_WEIGHT:
+                       break;
+               case CTX_MODE_PAINT_VERTEX:
+                       break;
+               case CTX_MODE_PAINT_TEXTURE:
+                       break;
+               case CTX_MODE_PARTICLE:
+                       break;
+               case CTX_MODE_OBJECT:
+                       break;
+       }
 }
 
-void *DRW_mode_framebuffer_list_get(void)
+static void DRW_engines_disable(void)
 {
-       return DST.fbl_mode;
+       BLI_freelistN(&DST.enabled_engines);
+}
+
+static int DRW_engines_get_hash(void)
+{
+       unsigned int hash = 0;
+       /* The cache depends on enabled engines */
+       /* FIXME : if collision occurs ... segfault */
+       for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
+               DrawEngineType *engine = link->data;
+               hash += BLI_ghashutil_strhash_p(engine->idname);
+       }
+
+       return hash;
+}
+
+/* Everything starts here.
+ * This function takes care of calling all cache and rendering functions
+ * for each relevant engine / mode engine. */
+void DRW_draw_view(const bContext *C)
+{
+       bool cache_is_dirty;
+       RegionView3D *rv3d = CTX_wm_region_view3d(C);
+       View3D *v3d = CTX_wm_view3d(C);
+       DST.viewport = rv3d->viewport;
+       v3d->zbuf = true;
+
+       /* Get list of enabled engines */
+       DRW_engines_enable(C);
+
+       /* Setup viewport */
+       cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash());
+       DRW_viewport_var_init(C);
+
+       /* Update ubos */
+       DRW_globals_update();
+
+       /* Init engines */
+       DRW_engines_init();
+
+       /* TODO : tag to refresh by the deps graph */
+       /* ideally only refresh when objects are added/removed */
+       /* or render properties / materials change */
+       if (cache_is_dirty) {
+               SceneLayer *sl = CTX_data_scene_layer(C);
+
+               DRW_engines_cache_init();
+               DEG_OBJECT_ITER(sl, ob);
+               {
+                       DRW_engines_cache_populate(ob);
+               }
+               DEG_OBJECT_ITER_END
+               DRW_engines_cache_finish();
+       }
+
+       /* Start Drawing */
+       DRW_engines_draw_background();
+
+       DRW_draw_callbacks_pre_scene();
+       DRW_engines_draw_scene();
+       DRW_draw_callbacks_post_scene();
+
+       DRW_draw_region_info();
+
+       DRW_state_reset();
+       DRW_engines_disable();
+
+       /* Unbind fbo and draw result */
+       GPU_viewport_unbind(DST.viewport);
+}
+
+/* ****************************************** OTHER ***************************************** */
+
+const bContext *DRW_get_context(void)
+{
+       return DST.context;
 }
 
 /* ****************************************** INIT ***************************************** */
 
-void DRW_engines_init(void)
+void DRW_engine_register(DrawEngineType *draw_engine_type)
+{
+       BLI_addtail(&DRW_engines, draw_engine_type);
+}
+
+void DRW_engines_register(void)
 {
 #ifdef WITH_CLAY_ENGINE
        RE_engines_register(NULL, &viewport_clay_type);
+
+       DRW_engine_register(&draw_engine_object_type);
+       DRW_engine_register(&draw_engine_edit_mesh_type);
+       DRW_engine_register(&draw_engine_edit_armature_type);
 #endif
 }
 
-extern struct GPUUniformBuffer *globals_ubo; /* draw_mode_pass.c */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
 void DRW_engines_free(void)
 {
 #ifdef WITH_CLAY_ENGINE
-       CLAY_engine_free();
+       DRW_shape_cache_free();
 
-       EDIT_MESH_engine_free();
+       DrawEngineType *next;
+       for (DrawEngineType *type = DRW_engines.first; type; type = next) {
+               next = type->next;
+               BLI_remlink(&R_engines, type);
 
-       DRW_shape_cache_free();
+               if (type->engine_free) {
+                       type->engine_free();
+               }
+       }
 
        if (globals_ubo)
                GPU_uniformbuffer_free(globals_ubo);
diff --git a/source/blender/draw/intern/draw_mode_pass.c b/source/blender/draw/intern/draw_mode_pass.c
deleted file mode 100644 (file)
index b21e6a2..0000000
+++ /dev/null
@@ -1,974 +0,0 @@
-/*
- * Copyright 2016, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Blender Institute
- *
- */
-
-/** \file blender/draw/intern/draw_mode_pass.c
- *  \ingroup draw
- */
-
-#include "DNA_camera_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_world_types.h"
-
-#include "GPU_shader.h"
-
-#include "UI_resources.h"
-
-#include "BKE_global.h"
-#include "BKE_camera.h"
-
-#include "DRW_render.h"
-
-#include "draw_mode_pass.h"
-
-/* ************************** OBJECT MODE ******************************* */
-
-/* Store list of shading group for easy access*/
-
-/* Empties */
-static DRWShadingGroup *plain_axes;
-static DRWShadingGroup *cube;
-static DRWShadingGroup *circle;
-static DRWShadingGroup *sphere;
-static DRWShadingGroup *cone;
-static DRWShadingGroup *single_arrow;
-static DRWShadingGroup *single_arrow_line;
-static DRWShadingGroup *arrows;
-static DRWShadingGroup *axis_names;
-
-/* Speaker */
-static DRWShadingGroup *speaker;
-
-/* Lamps */
-static DRWShadingGroup *lamp_center;
-static DRWShadingGroup *lamp_center_group;
-static DRWShadingGroup *lamp_groundpoint;
-static DRWShadingGroup *lamp_groundline;
-static DRWShadingGroup *lamp_circle;
-static DRWShadingGroup *lamp_circle_shadow;
-static DRWShadingGroup *lamp_sunrays;
-static DRWShadingGroup *lamp_distance;
-static DRWShadingGroup *lamp_buflimit;
-static DRWShadingGroup *lamp_buflimit_points;
-static DRWShadingGroup *lamp_area;
-static DRWShadingGroup *lamp_hemi;
-static DRWShadingGroup *lamp_spot_cone;
-static DRWShadingGroup *lamp_spot_blend;
-static DRWShadingGroup *lamp_spot_pyramid;
-static DRWShadingGroup *lamp_spot_blend_rect;
-
-/* Helpers */
-static DRWShadingGroup *relationship_lines;
-
-/* Objects Centers */
-static DRWShadingGroup *center_active;
-static DRWShadingGroup *center_selected;
-static DRWShadingGroup *center_deselected;
-
-/* Camera */
-static DRWShadingGroup *camera;
-static DRWShadingGroup *camera_tria;
-static DRWShadingGroup *camera_focus;
-static DRWShadingGroup *camera_clip;
-static DRWShadingGroup *camera_clip_points;
-static DRWShadingGroup *camera_mist;
-static DRWShadingGroup *camera_mist_points;
-
-/* Colors & Constant */
-GlobalsUboStorage ts;
-struct GPUUniformBuffer *globals_ubo = NULL;
-
-void DRW_update_global_values(void)
-{
-       UI_GetThemeColor4fv(TH_WIRE, ts.colorWire);
-       UI_GetThemeColor4fv(TH_WIRE_EDIT, ts.colorWireEdit);
-       UI_GetThemeColor4fv(TH_ACTIVE, ts.colorActive);
-       UI_GetThemeColor4fv(TH_SELECT, ts.colorSelect);
-       UI_GetThemeColor4fv(TH_TRANSFORM, ts.colorTransform);
-       UI_GetThemeColor4fv(TH_GROUP_ACTIVE, ts.colorGroupActive);
-       UI_GetThemeColor4fv(TH_GROUP, ts.colorGroup);
-       UI_GetThemeColor4fv(TH_LAMP, ts.colorLamp);
-       UI_GetThemeColor4fv(TH_SPEAKER, ts.colorSpeaker);
-       UI_GetThemeColor4fv(TH_CAMERA, ts.colorCamera);
-       UI_GetThemeColor4fv(TH_EMPTY, ts.colorEmpty);
-       UI_GetThemeColor4fv(TH_VERTEX, ts.colorVertex);
-       UI_GetThemeColor4fv(TH_VERTEX_SELECT, ts.colorVertexSelect);
-       UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, ts.colorEditMeshActive);
-       UI_GetThemeColor4fv(TH_EDGE_SELECT, ts.colorEdgeSelect);
-       UI_GetThemeColor4fv(TH_EDGE_SEAM, ts.colorEdgeSeam);
-       UI_GetThemeColor4fv(TH_EDGE_SHARP, ts.colorEdgeSharp);
-       UI_GetThemeColor4fv(TH_EDGE_CREASE, ts.colorEdgeCrease);
-       UI_GetThemeColor4fv(TH_EDGE_BEVEL, ts.colorEdgeBWeight);
-       UI_GetThemeColor4fv(TH_EDGE_FACESEL, ts.colorEdgeFaceSelect);
-       UI_GetThemeColor4fv(TH_FACE, ts.colorFace);
-       UI_GetThemeColor4fv(TH_FACE_SELECT, ts.colorFaceSelect);
-       UI_GetThemeColor4fv(TH_NORMAL, ts.colorNormal);
-       UI_GetThemeColor4fv(TH_VNORMAL, ts.colorVNormal);
-       UI_GetThemeColor4fv(TH_LNORMAL, ts.colorLNormal);
-       UI_GetThemeColor4fv(TH_FACE_DOT, ts.colorFaceDot);
-
-       UI_GetThemeColorShadeAlpha4fv(TH_TRANSFORM, 0, -80, ts.colorDeselect);
-       UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, ts.colorOutline);
-       UI_GetThemeColorShadeAlpha4fv(TH_LAMP, 0, 255, ts.colorLampNoAlpha);
-
-       ts.sizeLampCenter = (U.obcenter_dia + 1.5f) * U.pixelsize;
-       ts.sizeLampCircle = U.pixelsize * 9.0f;
-       ts.sizeLampCircleShadow = ts.sizeLampCircle + U.pixelsize * 3.0f;
-
-       /* M_SQRT2 to be at least the same size of the old square */
-       ts.sizeVertex = UI_GetThemeValuef(TH_VERTEX_SIZE) * M_SQRT2 / 2.0f;
-       ts.sizeFaceDot = UI_GetThemeValuef(TH_FACEDOT_SIZE) * M_SQRT2;
-       ts.sizeEdge = 1.0f / 2.0f; /* TODO Theme */
-       ts.sizeEdgeFix = 0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * M_SQRT1_2);
-       ts.sizeNormal = 1.0f; /* TODO compute */
-
-       /* TODO Waiting for notifiers to invalidate cache */
-       if (globals_ubo) {
-               DRW_uniformbuffer_free(globals_ubo);
-       }
-
-       globals_ubo = DRW_uniformbuffer_create(sizeof(GlobalsUboStorage), &ts);
-}
-
-/* Store list of passes for easy access */
-static DRWPass *wire_overlay;
-static DRWPass *wire_overlay_hidden_wire;
-static DRWPass *wire_outline;
-static DRWPass *non_meshes;
-static DRWPass *ob_center;
-static DRWPass *bone_solid;
-static DRWPass *bone_wire;
-
-static DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
-
-       DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
-       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4], float *size)
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
-
-       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
-       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-       DRW_shgroup_uniform_float(grp, "size", size, 1);
-       DRW_shgroup_state_set(grp, DRW_STATE_POINT);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float color[4])
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
-
-       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
-       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4])
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
-
-       DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
-       DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-       DRW_shgroup_state_set(grp, DRW_STATE_POINT);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Batch *geom, float *size)
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
-       DRW_shgroup_attrib_float(grp, "world_pos", 3);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       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_state_set(grp, DRW_STATE_STIPPLE_3);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_instance_objspace_solid(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
-{
-       static float light[3] = {0.0f, 0.0f, 1.0f};
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-       DRW_shgroup_attrib_float(grp, "color", 4);
-       DRW_shgroup_uniform_mat4(grp, "ModelMatrix", (float *)obmat);
-       DRW_shgroup_uniform_vec3(grp, "light", light, 1);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Batch *geom, float (*obmat)[4])
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-       DRW_shgroup_attrib_float(grp, "color", 4);
-       DRW_shgroup_uniform_mat4(grp, "ModelMatrix", (float *)obmat);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom)
-{
-       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       DRW_shgroup_attrib_float(grp, "size", 1);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-       DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
-{
-       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       DRW_shgroup_attrib_float(grp, "size", 1);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct Batch *geom)
-{
-       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       DRW_shgroup_attrib_float(grp, "corners", 8);
-       DRW_shgroup_attrib_float(grp, "depth", 1);
-       DRW_shgroup_attrib_float(grp, "tria", 4);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct Batch *geom)
-{
-       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES);
-       static float point_size = 4.0f;
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       DRW_shgroup_attrib_float(grp, "start", 1);
-       DRW_shgroup_attrib_float(grp, "end", 1);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-       DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
-
-       return grp;
-}
-
-static DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct Batch *geom)
-{
-       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR);
-       static bool True = true;
-       static bool False = false;
-
-       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
-       DRW_shgroup_attrib_float(grp, "color", 3);
-       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
-       DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
-       DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
-       DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
-
-       return grp;
-}
-
-/* This Function setup the passes needed for the mode rendering.
- * The passes are populated by the rendering engines using the DRW_shgroup_* functions.
- * If a pass is not needed use NULL instead of the pass pointer */
-void DRW_mode_passes_setup(DRWPass **psl_wire_overlay,
-                           DRWPass **psl_wire_overlay_hidden_wire,
-                           DRWPass **psl_wire_outline,
-                           DRWPass **psl_non_meshes,
-                           DRWPass **psl_ob_center,
-                           DRWPass **psl_bone_solid,
-                           DRWPass **psl_bone_wire)
-{
-
-
-       if (psl_wire_overlay) {
-               /* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND;
-               *psl_wire_overlay = DRW_pass_create("Wire Overlays Pass", state);
-       }
-
-       if (psl_wire_overlay_hidden_wire) {
-               /* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
-               *psl_wire_overlay_hidden_wire = DRW_pass_create("Wire Overlays Pass", state);
-       }
-
-       if (psl_wire_outline) {
-               /* This pass can draw mesh outlines and/or fancy wireframe */
-               /* Fancy wireframes are not meant to be occluded (without Z offset) */
-               /* Outlines and Fancy Wires use the same VBO */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
-               *psl_wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
-       }
-
-       if (psl_bone_solid) {
-               /* Solid bones */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
-               *psl_bone_solid = DRW_pass_create("Bone Solid Pass", state);
-       }
-
-       if (psl_bone_wire) {
-               /* Wire bones */
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
-               *psl_bone_wire = DRW_pass_create("Bone Wire Pass", state);
-       }
-
-       if (psl_non_meshes) {
-               /* Non Meshes Pass (Camera, empties, lamps ...) */
-               struct Batch *geom;
-
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_POINT;
-               state |= DRW_STATE_WIRE;
-               *psl_non_meshes = DRW_pass_create("Non Meshes Pass", state);
-
-               /* Empties */
-               geom = DRW_cache_plain_axes_get();
-               plain_axes = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_cube_get();
-               cube = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_circle_get();
-               circle = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_empty_sphere_get();
-               sphere = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_empty_cone_get();
-               cone = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_arrow_get();
-               single_arrow = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_line_get();
-               single_arrow_line = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_arrows_get();
-               arrows = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_axis_names_get();
-               axis_names = shgroup_instance_axis_names(*psl_non_meshes, geom);
-
-               /* Speaker */
-               geom = DRW_cache_speaker_get();
-               speaker = shgroup_instance(*psl_non_meshes, geom);
-
-               /* Camera */
-               geom = DRW_cache_camera_get();
-               camera = shgroup_camera_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_camera_tria_get();
-               camera_tria = shgroup_camera_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_plain_axes_get();
-               camera_focus = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_line_get();
-               camera_clip = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-               camera_mist = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_line_endpoints_get();
-               camera_clip_points = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-               camera_mist_points = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-
-               /* Lamps */
-               /* TODO
-                * for now we create multiple times the same VBO with only lamp center coordinates
-                * but ideally we would only create it once */
-
-               /* start with buflimit because we don't want stipples */
-               geom = DRW_cache_single_line_get();
-               lamp_buflimit = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-
-               lamp_center = shgroup_dynpoints_uniform_color(*psl_non_meshes, ts.colorLampNoAlpha, &ts.sizeLampCenter);
-               lamp_center_group = shgroup_dynpoints_uniform_color(*psl_non_meshes, ts.colorGroup, &ts.sizeLampCenter);
-
-               geom = DRW_cache_lamp_get();
-               lamp_circle = shgroup_instance_screenspace(*psl_non_meshes, geom, &ts.sizeLampCircle);
-               lamp_circle_shadow = shgroup_instance_screenspace(*psl_non_meshes, geom, &ts.sizeLampCircleShadow);
-
-               geom = DRW_cache_lamp_sunrays_get();
-               lamp_sunrays = shgroup_instance_screenspace(*psl_non_meshes, geom, &ts.sizeLampCircle);
-
-               lamp_groundline = shgroup_groundlines_uniform_color(*psl_non_meshes, ts.colorLamp);
-               lamp_groundpoint = shgroup_groundpoints_uniform_color(*psl_non_meshes, ts.colorLamp);
-
-               geom = DRW_cache_lamp_area_get();
-               lamp_area = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_lamp_hemi_get();
-               lamp_hemi = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_line_get();
-               lamp_distance = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_single_line_endpoints_get();
-               lamp_buflimit_points = shgroup_distance_lines_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_lamp_spot_get();
-               lamp_spot_cone = shgroup_spot_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_circle_get();
-               lamp_spot_blend = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_lamp_spot_square_get();
-               lamp_spot_pyramid = shgroup_instance(*psl_non_meshes, geom);
-
-               geom = DRW_cache_square_get();
-               lamp_spot_blend_rect = shgroup_instance(*psl_non_meshes, geom);
-
-               /* Relationship Lines */
-               relationship_lines = shgroup_dynlines_uniform_color(*psl_non_meshes, ts.colorWire);
-               DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
-       }
-
-       if (psl_ob_center) {
-               /* Object Center pass grouped by State */
-               DRWShadingGroup *grp;
-               static float outlineWidth, size;
-
-               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
-               *psl_ob_center = DRW_pass_create("Obj Center Pass", state);
-
-               outlineWidth = 1.0f * U.pixelsize;
-               size = U.obcenter_dia * U.pixelsize + outlineWidth;
-
-               GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
-
-               /* Active */
-               grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
-               DRW_shgroup_uniform_float(grp, "size", &size, 1);
-               DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
-               DRW_shgroup_uniform_vec4(grp, "color", ts.colorActive, 1);
-               DRW_shgroup_uniform_vec4(grp, "outlineColor", ts.colorOutline, 1);
-               center_active = grp;
-
-               /* Select */
-               grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
-               DRW_shgroup_uniform_vec4(grp, "color", ts.colorSelect, 1);
-               center_selected = grp;
-
-               /* Deselect */
-               grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
-               DRW_shgroup_uniform_vec4(grp, "color", ts.colorDeselect, 1);
-               center_deselected = grp;
-       }
-
-       /* Save passes refs */
-       wire_overlay = (psl_wire_overlay) ? *psl_wire_overlay : NULL;
-       wire_overlay_hidden_wire = (psl_wire_overlay_hidden_wire) ? *psl_wire_overlay_hidden_wire : NULL;
-       wire_outline = (psl_wire_outline) ? *psl_wire_outline : NULL;
-       non_meshes = (psl_non_meshes) ? *psl_non_meshes : NULL;
-       ob_center = (psl_ob_center) ? *psl_ob_center : NULL;
-       bone_solid = (psl_bone_solid) ? *psl_bone_solid : NULL;
-       bone_wire = (psl_bone_wire) ? *psl_bone_wire : NULL;
-}
-
-/* ******************************************** WIRES *********************************************** */
-
-/* TODO FINISH */
-/* Get the wire color theme_id of an object based on it's state
- * **color is a way to get a pointer to the static color var associated */
-static int draw_object_wire_theme(Object *ob, float **color)
-{
-       const bool is_edit = (ob->mode & OB_MODE_EDIT) != 0;
-       /* confusing logic here, there are 2 methods of setting the color
-        * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
-        *
-        * note: no theme yet for 'colindex' */
-       int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
-
-       if (//(scene->obedit == NULL) &&
-           ((G.moving & G_TRANSFORM_OBJ) != 0) &&
-           ((ob->base_flag & BASE_SELECTED) != 0))
-       {
-               theme_id = TH_TRANSFORM;
-       }
-       else {
-               /* Sets the 'theme_id' or fallback to wire */
-               if ((ob->flag & OB_FROMGROUP) != 0) {
-                       if ((ob->base_flag & BASE_SELECTED) != 0) {
-                               /* uses darker active color for non-active + selected */
-                               theme_id = TH_GROUP_ACTIVE;
-
-                               // if (scene->basact != base) {
-                               //      theme_shade = -16;
-                               // }
-                       }
-                       else {
-                               theme_id = TH_GROUP;
-                       }
-               }
-               else {
-                       if ((ob->base_flag & BASE_SELECTED) != 0) {
-                               theme_id = //scene->basact == base ? TH_ACTIVE :
-                               TH_SELECT;
-                       }
-                       else {
-                               if (ob->type == OB_LAMP) theme_id = TH_LAMP;
-                               else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
-                               else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
-                               else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
-                               /* fallback to TH_WIRE */
-                       }
-               }
-       }
-
-       if (color != NULL) {
-               switch (theme_id) {
-                       case TH_WIRE_EDIT:    *color = ts.colorTransform; break;
-                       case TH_ACTIVE:       *color = ts.colorActive; break;
-                       case TH_SELECT:       *color = ts.colorSelect; break;
-                       case TH_GROUP:        *color = ts.colorGroup; break;
-                       case TH_GROUP_ACTIVE: *color = ts.colorGroupActive; break;
-                       case TH_TRANSFORM:    *color = ts.colorTransform; break;
-                       case OB_SPEAKER:      *color = ts.colorSpeaker; break;
-                       case OB_CAMERA:       *color = ts.colorCamera; break;
-                       case OB_EMPTY:        *color = ts.colorEmpty; break;
-                       case OB_LAMP:         *color = ts.colorLamp; break;
-                       default:              *color = ts.colorWire; break;
-               }
-       }
-
-       return theme_id;
-}
-
-void DRW_shgroup_wire_outline(Object *ob, const bool do_front, const bool do_back, const bool do_outline)
-{
-       GPUShader *sh;
-       struct Batch *geom = DRW_cache_wire_outline_get(ob);
-
-       float *color;
-       draw_object_wire_theme(ob, &color);
-
-#if 1 /* New wire */
-
-       bool is_perps = DRW_viewport_is_persp_get();
-       static bool bTrue = true;
-       static bool bFalse = false;
-
-       /* Note (TODO) : this requires cache to be discarded on ortho/perp switch
-        * It may be preferable (or not depending on performance implication)
-        * to introduce a shader uniform switch */
-       if (is_perps) {
-               sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_PERSP);
-       }
-       else {
-               sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
-       }
-
-       if (do_front || do_back) {
-               bool *bFront = (do_front) ? &bTrue : &bFalse;
-               bool *bBack = (do_back) ? &bTrue : &bFalse;
-
-               DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
-               DRW_shgroup_state_set(grp, DRW_STATE_WIRE);
-               DRW_shgroup_uniform_vec4(grp, "frontColor", color, 1);
-               DRW_shgroup_uniform_vec4(grp, "backColor", color, 1);
-               DRW_shgroup_uniform_bool(grp, "drawFront", bFront, 1);
-               DRW_shgroup_uniform_bool(grp, "drawBack", bBack, 1);
-               DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bFalse, 1);
-               DRW_shgroup_call_add(grp, geom, ob->obmat);
-       }
-
-       if (do_outline) {
-               DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
-               DRW_shgroup_state_set(grp, DRW_STATE_WIRE_LARGE);
-               DRW_shgroup_uniform_vec4(grp, "silhouetteColor", color, 1);
-               DRW_shgroup_uniform_bool(grp, "drawFront", &bFalse, 1);
-               DRW_shgroup_uniform_bool(grp, "drawBack", &bFalse, 1);
-               DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bTrue, 1);
-
-               DRW_shgroup_call_add(grp, geom, ob->obmat);
-       }
-
-#else /* Old (flat) wire */
-
-       sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
-       DRWShadingGroup *grp = DRW_shgroup_create(sh, wire_outline);
-       DRW_shgroup_state_set(grp, DRW_STATE_WIRE_LARGE);
-       DRW_shgroup_uniform_vec4(grp, "color", frontcol, 1);
-
-       DRW_shgroup_call_add(grp, geom, ob->obmat);
-#endif
-
-}
-
-/* ***************************** NON MESHES ********************** */
-
-void DRW_shgroup_lamp(Object *ob)
-{
-       Lamp *la = ob->data;
-       float *color;
-       int theme_id = draw_object_wire_theme(ob, &color);
-       static float zero = 0.0f;
-
-       /* Don't draw the center if it's selected or active */
-       if (theme_id == TH_GROUP)
-               DRW_shgroup_dynamic_call_add(lamp_center_group, ob->obmat[3]);
-       else if (theme_id == TH_LAMP)
-               DRW_shgroup_dynamic_call_add(lamp_center, ob->obmat[3]);
-
-       /* First circle */
-       DRW_shgroup_dynamic_call_add(lamp_circle, ob->obmat[3], color);
-
-       /* 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))) {
-                       DRW_shgroup_dynamic_call_add(lamp_circle_shadow, ob->obmat[3], color);
-               }
-       }
-
-       /* Distance */
-       if (ELEM(la->type, LA_HEMI, LA_SUN, LA_AREA)) {
-               DRW_shgroup_dynamic_call_add(lamp_distance, color, &zero, &la->dist, ob->obmat);
-       }
-
-       copy_m4_m4(la->shapemat, ob->obmat);
-
-       if (la->type == LA_SUN) {
-               DRW_shgroup_dynamic_call_add(lamp_sunrays, ob->obmat[3], color);
-       }
-       else if (la->type == LA_SPOT) {
-               float size[3], sizemat[4][4];
-               static float one = 1.0f;
-               float blend = 1.0f - pow2f(la->spotblend);
-
-               size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist;
-               size[2] = cosf(la->spotsize * 0.5f) * la->dist;
-
-               size_to_mat4(sizemat, size);
-               mul_m4_m4m4(la->spotconemat, 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);
-
-               if (la->mode & LA_SQUARE) {
-                       DRW_shgroup_dynamic_call_add(lamp_spot_pyramid,    color, &one, la->spotconemat);
-
-                       /* 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(lamp_spot_blend_rect, color, &one, la->spotblendmat);
-                       }
-               }
-               else {
-                       DRW_shgroup_dynamic_call_add(lamp_spot_cone,  color, la->spotconemat);
-
-                       /* 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(lamp_spot_blend, color, &one, la->spotblendmat);
-                       }
-               }
-
-               normalize_m4(la->shapemat);
-               DRW_shgroup_dynamic_call_add(lamp_buflimit,        color, &la->clipsta, &la->clipend, ob->obmat);
-               DRW_shgroup_dynamic_call_add(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(lamp_hemi, color, &hemisize, la->shapemat);
-       }
-       else if (la->type == LA_AREA) {
-               float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
-
-               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);
-               }
-
-               DRW_shgroup_dynamic_call_add(lamp_area, color, &la->area_size, la->shapemat);
-       }
-
-       /* Line and point going to the ground */
-       DRW_shgroup_dynamic_call_add(lamp_groundline, ob->obmat[3]);
-       DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]);
-}
-
-void DRW_shgroup_camera(Object *ob)
-{
-       const struct bContext *C = DRW_get_context();
-       View3D *v3d = CTX_wm_view3d(C);
-       Scene *scene = CTX_data_scene(C);
-
-       Camera *cam = ob->data;
-       const bool is_active = (ob == v3d->camera);
-       float *color;
-       draw_object_wire_theme(ob, &color);
-
-       float vec[4][3], asp[2], shift[2], scale[3], drawsize;
-
-       scale[0] = 1.0f / len_v3(ob->obmat[0]);
-       scale[1] = 1.0f / len_v3(ob->obmat[1]);
-       scale[2] = 1.0f / len_v3(ob->obmat[2]);
-
-       BKE_camera_view_frame_ex(scene, cam, cam->drawsize, false, scale,
-                                asp, shift, &drawsize, vec);
-
-       // /* Frame coords */
-       copy_v2_v2(cam->drwcorners[0], vec[0]);
-       copy_v2_v2(cam->drwcorners[1], vec[1]);
-       copy_v2_v2(cam->drwcorners[2], vec[2]);
-       copy_v2_v2(cam->drwcorners[3], vec[3]);
-
-       /* depth */
-       cam->drwdepth = vec[0][2];
-
-       /* tria */
-       cam->drwtria[0][0] = shift[0] + ((0.7f * drawsize) * scale[0]);
-       cam->drwtria[0][1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
-       cam->drwtria[1][0] = shift[0];
-       cam->drwtria[1][1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
-
-       DRW_shgroup_dynamic_call_add(camera, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
-
-       /* Active cam */
-       if (is_active) {
-               DRW_shgroup_dynamic_call_add(camera_tria, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
-       }
-
-       /* draw the rest in normalize object space */
-       copy_m4_m4(cam->drwnormalmat, ob->obmat);
-       normalize_m4(cam->drwnormalmat);
-
-       if (cam->flag & CAM_SHOWLIMITS) {
-               static float col[3] = {0.5f, 0.5f, 0.25f}, col_hi[3] = {1.0f, 1.0f, 0.5f};
-               float sizemat[4][4], size[3] = {1.0f, 1.0f, 0.0f};
-               float focusdist = BKE_camera_object_dof_distance(ob);
-
-               copy_m4_m4(cam->drwfocusmat, cam->drwnormalmat);
-               translate_m4(cam->drwfocusmat, 0.0f, 0.0f, -focusdist);
-               size_to_mat4(sizemat, size);
-               mul_m4_m4m4(cam->drwfocusmat, cam->drwfocusmat, sizemat);
-
-               DRW_shgroup_dynamic_call_add(camera_focus, (is_active ? col_hi : col), &cam->drawsize, cam->drwfocusmat);
-
-               DRW_shgroup_dynamic_call_add(camera_clip, color, &cam->clipsta, &cam->clipend, cam->drwnormalmat);
-               DRW_shgroup_dynamic_call_add(camera_clip_points, (is_active ? col_hi : col), &cam->clipsta, &cam->clipend, cam->drwnormalmat);
-       }
-
-       if (cam->flag & CAM_SHOWMIST) {
-               World *world = scene->world;
-
-               if (world) {
-                       static float col[3] = {0.5f, 0.5f, 0.5f}, col_hi[3] = {1.0f, 1.0f, 1.0f};
-                       world->mistend = world->miststa + world->mistdist;
-                       DRW_shgroup_dynamic_call_add(camera_mist,        color, &world->miststa, &world->mistend, cam->drwnormalmat);
-                       DRW_shgroup_dynamic_call_add(camera_mist_points, (is_active ? col_hi : col), &world->miststa, &world->mistend, cam->drwnormalmat);
-               }
-       }
-}
-
-void DRW_shgroup_empty(Object *ob)
-{
-       float *color;
-       draw_object_wire_theme(ob, &color);
-
-       switch (ob->empty_drawtype) {
-               case OB_PLAINAXES:
-                       DRW_shgroup_dynamic_call_add(plain_axes, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_SINGLE_ARROW:
-                       DRW_shgroup_dynamic_call_add(single_arrow, color, &ob->empty_drawsize, ob->obmat);
-                       DRW_shgroup_dynamic_call_add(single_arrow_line, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_CUBE:
-                       DRW_shgroup_dynamic_call_add(cube, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_CIRCLE:
-                       DRW_shgroup_dynamic_call_add(circle, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_EMPTY_SPHERE:
-                       DRW_shgroup_dynamic_call_add(sphere, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_EMPTY_CONE:
-                       DRW_shgroup_dynamic_call_add(cone, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-               case OB_ARROWS:
-                       DRW_shgroup_dynamic_call_add(arrows, color, &ob->empty_drawsize, ob->obmat);
-                       DRW_shgroup_dynamic_call_add(axis_names, color, &ob->empty_drawsize, ob->obmat);
-                       break;
-       }
-}
-
-void DRW_shgroup_speaker(Object *ob)
-{
-       float *color;
-       static float one = 1.0f;
-       draw_object_wire_theme(ob, &color);
-
-       DRW_shgroup_dynamic_call_add(speaker, color, &one, ob->obmat);
-}
-
-void DRW_shgroup_relationship_lines(Object *ob)
-{
-       if (ob->parent) {
-               DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]);
-               DRW_shgroup_dynamic_call_add(relationship_lines, ob->parent->obmat[3]);
-       }
-}
-
-/* ***************************** COMMON **************************** */
-
-void DRW_shgroup_object_center(Object *ob)
-{
-       if ((ob->base_flag & BASE_SELECTED) != 0) {
-               DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);
-       }
-       else if (0) {
-               DRW_shgroup_dynamic_call_add(center_deselected, ob->obmat[3]);
-       }
-}
-
-/* *************************** ARMATURES ***************************** */
-
-static Object *current_armature;
-/* Reset when changing current_armature */
-static DRWShadingGroup *bone_octahedral_solid;
-static DRWShadingGroup *bone_octahedral_wire;
-static DRWShadingGroup *bone_point_solid;
-static DRWShadingGroup *bone_point_wire;
-static DRWShadingGroup *bone_axes;
-
-/* this function set the object space to use
- * for all subsequent DRW_shgroup_bone_*** calls */
-static void DRW_shgroup_armature(Object *ob)
-{
-       current_armature = ob;
-       bone_octahedral_solid = NULL;
-       bone_octahedral_wire = NULL;
-       bone_point_solid = NULL;
-       bone_point_wire = NULL;
-       bone_axes = NULL;
-}
-
-void DRW_shgroup_armature_object(Object *ob)
-{
-       float *color;
-       draw_object_wire_theme(ob, &color);
-
-       DRW_shgroup_armature(ob);
-       draw_armature_pose(ob, color);
-}
-
-void DRW_shgroup_armature_pose(Object *ob)
-{
-       DRW_shgroup_armature(ob);
-       draw_armature_pose(ob, NULL);
-}
-
-void DRW_shgroup_armature_edit(Object *ob)
-{
-       DRW_shgroup_armature(ob);
-       draw_armature_edit(ob);
-}
-
-/* Octahedral */
-void DRW_shgroup_bone_octahedral_solid(const float (*bone_mat)[4], const float color[4])
-{
-       if (bone_octahedral_solid == NULL) {
-               struct Batch *geom = DRW_cache_bone_octahedral_get();
-               bone_octahedral_solid = shgroup_instance_objspace_solid(bone_solid, geom, current_armature->obmat);
-       }
-
-       DRW_shgroup_dynamic_call_add(bone_octahedral_solid, bone_mat, color);
-}
-
-void DRW_shgroup_bone_octahedral_wire(const float (*bone_mat)[4], const float color[4])
-{
-       if (bone_octahedral_wire == NULL) {
-               struct Batch *geom = DRW_cache_bone_octahedral_wire_outline_get();
-               bone_octahedral_wire = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
-       }
-
-       DRW_shgroup_dynamic_call_add(bone_octahedral_wire, bone_mat, color);
-}
-
-/* Head and tail sphere */
-void DRW_shgroup_bone_point_solid(const float (*bone_mat)[4], const float color[4])
-{
-       if (bone_point_solid == NULL) {
-               struct Batch *geom = DRW_cache_bone_point_get();
-               bone_point_solid = shgroup_instance_objspace_solid(bone_solid, geom, current_armature->obmat);
-       }
-
-       DRW_shgroup_dynamic_call_add(bone_point_solid, bone_mat, color);
-}
-
-void DRW_shgroup_bone_point_wire(const float (*bone_mat)[4], const float color[4])
-{
-       if (bone_point_wire == NULL) {
-               struct Batch *geom = DRW_cache_bone_point_wire_outline_get();
-               bone_point_wire = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
-       }
-
-       DRW_shgroup_dynamic_call_add(bone_point_wire, bone_mat, color);
-}
-
-/* Axes */
-void DRW_shgroup_bone_axes(const float (*bone_mat)[4], const float color[4])
-{
-       if (bone_axes == NULL) {
-               struct Batch *geom = DRW_cache_bone_arrows_get();
-               bone_axes = shgroup_instance_objspace_wire(bone_wire, geom, current_armature->obmat);
-       }
-
-       DRW_shgroup_dynamic_call_add(bone_axes, bone_mat, color);
-}
-
-
-void DRW_shgroup_bone_relationship_lines(const float head[3], const float tail[3])
-{
-       DRW_shgroup_dynamic_call_add(relationship_lines, head);
-       DRW_shgroup_dynamic_call_add(relationship_lines, tail);
-}
similarity index 73%
rename from source/blender/draw/modes/object_mode.h
rename to source/blender/draw/modes/draw_mode_engines.h
index fda9096..01af249 100644 (file)
  *
  */
 
-/** \file blender/draw/modes/object_mode.h
+/** \file blender/draw/modes/draw_mode_engines.h
  *  \ingroup draw
  */
 
-#ifndef __OBJECT_MODE_H__
-#define __OBJECT_MODE_H__
+#ifndef __DRAW_MODES_ENGINES_H__
+#define __DRAW_MODES_ENGINES_H__
 
-struct Object;
+extern DrawEngineType draw_engine_object_type;
+extern DrawEngineType draw_engine_edit_mesh_type;
+extern DrawEngineType draw_engine_edit_armature_type;
 
-void OBJECT_cache_init(void);
-void OBJECT_cache_populate(struct Object *ob);
-void OBJECT_cache_finish(void);
-
-void OBJECT_draw(void);
-
-#endif /* __OBJECT_MODE_H__ */
\ No newline at end of file
+#endif /* __DRAW_MODES_ENGINES_H__ */
\ No newline at end of file
index 5f14183..f2f19ea 100644 (file)
 
 #include "DNA_armature_types.h"
 
-#include "draw_mode_pass.h"
+#include "draw_common.h"
 
-#include "edit_armature_mode.h"
+#include "draw_mode_engines.h"
 
 /* keep it under MAX_PASSES */
 typedef struct EDIT_ARMATURE_PassList {
-       struct DRWPass *non_meshes_pass;
-       struct DRWPass *ob_center_pass;
-       struct DRWPass *wire_outline_pass;
-       struct DRWPass *bone_solid_pass;
-       struct DRWPass *bone_wire_pass;
+       struct DRWPass *bone_solid;
+       struct DRWPass *bone_wire;
+       struct DRWPass *relationship;
 } EDIT_ARMATURE_PassList;
 
-void EDIT_ARMATURE_cache_init(void)
+typedef struct EDIT_ARMATURE_Data {
+       char engine_name[32];
+       void *fbl;
+       void *txl;
+       EDIT_ARMATURE_PassList *psl;
+       void *stl;
+} EDIT_ARMATURE_Data;
+
+static DRWShadingGroup *relationship_lines;
+
+extern GlobalsUboStorage ts;
+
+static EDIT_ARMATURE_Data *vedata;
+
+static void EDIT_ARMATURE_cache_init(void)
 {
-       EDIT_ARMATURE_PassList *psl = DRW_mode_pass_list_get();
-       static struct GPUShader *depth_sh;
+       vedata = DRW_viewport_engine_data_get("EditArmatureMode");
+       EDIT_ARMATURE_PassList *psl = vedata->psl;
 
-       if (!depth_sh) {
-               depth_sh = DRW_shader_create_3D_depth_only();
+       {
+               /* Solid bones */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+               psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
        }
 
-       DRW_mode_passes_setup(NULL,
-                             NULL,
-                             &psl->wire_outline_pass,
-                             &psl->non_meshes_pass,
-                             &psl->ob_center_pass,
-                             &psl->bone_solid_pass,
-                             &psl->bone_wire_pass);
-}
+       {
+               /* Wire bones */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+               psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
+       }
 
-void EDIT_ARMATURE_cache_populate(Object *ob)
-{
-       bArmature *arm = ob->data;
+       {
+               /* Non Meshes Pass (Camera, empties, lamps ...) */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
+               psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
 
-       switch (ob->type) {
-               case OB_ARMATURE:
-                       /* detect Edit Armature mode */
-                       if (arm->edbo)
-                               DRW_shgroup_armature_edit(ob);
-                       else
-                               DRW_shgroup_armature_object(ob);
-                       break;
-               case OB_MESH:
-                       break;
-               case OB_LAMP:
-                       DRW_shgroup_lamp(ob);
-                       break;
-               case OB_CAMERA:
-                       DRW_shgroup_camera(ob);
-                       break;
-               case OB_EMPTY:
-                       DRW_shgroup_empty(ob);
-                       break;
-               case OB_SPEAKER:
-                       DRW_shgroup_speaker(ob);
-                       break;
-               default:
-                       break;
+               /* Relationship Lines */
+               relationship_lines = shgroup_dynlines_uniform_color(psl->relationship, ts.colorWire);
+               DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
        }
 
-       DRW_shgroup_object_center(ob);
-       DRW_shgroup_relationship_lines(ob);
 }
 
-void EDIT_ARMATURE_cache_finish(void)
+static void EDIT_ARMATURE_cache_populate(Object *ob)
 {
-       /* Do nothing */
+       bArmature *arm = ob->data;
+       EDIT_ARMATURE_PassList *psl = vedata->psl;
+
+       if (ob->type == OB_ARMATURE) {
+               if (arm->edbo) {
+                       DRW_shgroup_armature_edit(ob, psl->bone_solid, psl->bone_wire, relationship_lines);
+               }
+       }
 }
 
-void EDIT_ARMATURE_draw(void)
+static void EDIT_ARMATURE_draw_scene(void)
 {
-       EDIT_ARMATURE_PassList *psl = DRW_mode_pass_list_get();
+       EDIT_ARMATURE_Data *ved = DRW_viewport_engine_data_get("EditArmatureMode");
+       EDIT_ARMATURE_PassList *psl = ved->psl;
 
-       DRW_draw_pass(psl->bone_solid_pass);
-       DRW_draw_pass(psl->bone_wire_pass);
-       DRW_draw_pass(psl->wire_outline_pass);
-       DRW_draw_pass(psl->non_meshes_pass);
-       DRW_draw_pass(psl->ob_center_pass);
+       DRW_draw_pass(psl->bone_solid);
+       DRW_draw_pass(psl->bone_wire);
+       DRW_draw_pass(psl->relationship);
 }
 
 void EDIT_ARMATURE_collection_settings_create(CollectionEngineSettings *ces)
@@ -114,3 +109,15 @@ void EDIT_ARMATURE_collection_settings_create(CollectionEngineSettings *ces)
        BLI_assert(ces);
        //BKE_collection_engine_property_add_int(ces, "show_occlude_wire", false);
 }
+
+DrawEngineType draw_engine_edit_armature_type = {
+       NULL, NULL,
+       N_("EditArmatureMode"),
+       NULL,
+       NULL,
+       &EDIT_ARMATURE_cache_init,
+       &EDIT_ARMATURE_cache_populate,
+       NULL,
+       NULL,
+       &EDIT_ARMATURE_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_armature_mode.h b/source/blender/draw/modes/edit_armature_mode.h
deleted file mode 100644 (file)
index 89354cd..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Blender Institute
- *
- */
-
-/** \file blender/draw/modes/edit_armature_mode.h
- *  \ingroup draw
- */
-
-#ifndef __EDIT_ARMATURE_MODE_H__
-#define __EDIT_ARMATURE_MODE_H__
-
-struct Object;
-
-void EDIT_ARMATURE_cache_init(void);
-void EDIT_ARMATURE_cache_populate(struct Object *ob);
-void EDIT_ARMATURE_cache_finish(void);
-
-void EDIT_ARMATURE_draw(void);
-
-#endif /* __EDIT_ARMATURE_MODE_H__ */
\ No newline at end of file
index 3736369..e671e9f 100644 (file)
 #include "DRW_render.h"
 
 #include "GPU_shader.h"
-#include "GPU_viewport.h"
 #include "DNA_view3d_types.h"
 
-#include "draw_mode_pass.h"
+#include "draw_common.h"
 
-#include "edit_mesh_mode.h"
+#include "draw_mode_engines.h"
 
 /* keep it under MAX_PASSES */
 typedef struct EDIT_MESH_PassList {
-       struct DRWPass *non_meshes_pass;
-       struct DRWPass *ob_center_pass;
-       struct DRWPass *wire_outline_pass;
        struct DRWPass *depth_pass_hidden_wire;
        struct DRWPass *edit_face_overlay_pass;
        struct DRWPass *edit_face_occluded_pass;
@@ -57,6 +53,14 @@ typedef struct EDIT_MESH_TextureList {
        struct GPUTexture *occlude_wire_color_tx;
 } EDIT_MESH_TextureList;
 
+typedef struct EDIT_MESH_Data {
+       char engine_name[32];
+       EDIT_MESH_FramebufferList *fbl;
+       EDIT_MESH_TextureList *txl;
+       EDIT_MESH_PassList *psl;
+       void *stl;
+} EDIT_MESH_Data;
+
 static DRWShadingGroup *depth_shgrp_hidden_wire;
 
 static DRWShadingGroup *face_overlay_shgrp;
@@ -70,7 +74,7 @@ static DRWShadingGroup *lverts_occluded_shgrp;
 static DRWShadingGroup *facedot_occluded_shgrp;
 static DRWShadingGroup *facefill_occluded_shgrp;
 
-extern struct GPUUniformBuffer *globals_ubo; /* draw_mode_pass.c */
+extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
 
 static struct GPUShader *overlay_tri_sh = NULL;
 static struct GPUShader *overlay_tri_fast_sh = NULL;
@@ -95,10 +99,11 @@ extern char datatoc_edit_overlay_mix_frag_glsl[];
 extern char datatoc_edit_overlay_facefill_vert_glsl[];
 extern char datatoc_edit_overlay_facefill_frag_glsl[];
 
-void EDIT_MESH_init(void)
+static void EDIT_MESH_engine_init(void)
 {
-       EDIT_MESH_TextureList *txl = DRW_mode_texture_list_get();
-       EDIT_MESH_FramebufferList *fbl = DRW_mode_framebuffer_list_get();
+       EDIT_MESH_Data *vedata = DRW_viewport_engine_data_get("EditMeshMode");
+       EDIT_MESH_TextureList *txl = vedata->txl;
+       EDIT_MESH_FramebufferList *fbl = vedata->fbl;
 
        float *viewport_size = DRW_viewport_size_get();
 
@@ -209,9 +214,13 @@ static DRWPass *edit_mesh_create_overlay_pass(DRWShadingGroup **face_shgrp, DRWS
 static float backwire_opacity;
 static float face_mod;
 
-void EDIT_MESH_cache_init(void)
+static void EDIT_MESH_cache_init(void)
 {
-       EDIT_MESH_PassList *psl = DRW_mode_pass_list_get();
+       EDIT_MESH_Data *vedata = DRW_viewport_engine_data_get("EditMeshMode");
+       EDIT_MESH_TextureList *txl = vedata->txl;
+       EDIT_MESH_PassList *psl = vedata->psl;
+       DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
        const struct bContext *C = DRW_get_context();
        View3D *v3d = CTX_wm_view3d(C);
 
@@ -242,12 +251,9 @@ void EDIT_MESH_cache_init(void)
                DRW_shgroup_uniform_block(facefill_occluded_shgrp, "globalsBlock", globals_ubo, 0);
 
                /* we need a full screen pass to combine the result */
-               EDIT_MESH_TextureList *txl = DRW_mode_texture_list_get();
-               DefaultTextureList *dtxl = DRW_engine_texture_list_get();
                struct Batch *quad = DRW_cache_fullscreen_quad_get();
                static float mat[4][4]; /* not even used but avoid crash */
 
-
                psl->mix_occlude_pass = DRW_pass_create("Mix Occluded Wires", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
                DRWShadingGroup *mix_shgrp = DRW_shgroup_create(overlay_mix_sh, psl->mix_occlude_pass);
                DRW_shgroup_call_add(mix_shgrp, quad, mat);
@@ -256,14 +262,6 @@ void EDIT_MESH_cache_init(void)
                DRW_shgroup_uniform_buffer(mix_shgrp, "wireDepth", &txl->occlude_wire_depth_tx, 2);
                DRW_shgroup_uniform_buffer(mix_shgrp, "sceneDepth", &dtxl->depth, 3);
        }
-
-       DRW_mode_passes_setup(NULL,
-                             NULL,
-                             &psl->wire_outline_pass,
-                             &psl->non_meshes_pass,
-                             &psl->ob_center_pass,
-                             NULL,
-                             NULL);
 }
 
 static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp,
@@ -288,7 +286,7 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, DRWShadingGroup *
        }
 }
 
-void EDIT_MESH_cache_populate(Object *ob)
+static void EDIT_MESH_cache_populate(Object *ob)
 {
        const struct bContext *C = DRW_get_context();
        View3D *v3d = CTX_wm_view3d(C);
@@ -296,64 +294,38 @@ void EDIT_MESH_cache_populate(Object *ob)
        Object *obedit = scene->obedit;
        struct Batch *geom;
 
-       CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
-       bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
-       backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* should be done only once */
-
-       face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
-
-       switch (ob->type) {
-               case OB_MESH:
-                       if (ob == obedit) {     
-                               if (do_occlude_wire) {
-                                       geom = DRW_cache_surface_get(ob);
-                                       DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
-                               }
-
-                               if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
-                                       edit_mesh_add_ob_to_pass(scene, ob, face_occluded_shgrp, ledges_occluded_shgrp,
-                                                                lverts_occluded_shgrp, facedot_occluded_shgrp, facefill_occluded_shgrp);
-                               }
-                               else {
-                                       edit_mesh_add_ob_to_pass(scene, ob, face_overlay_shgrp, ledges_overlay_shgrp,
-                                                                lverts_overlay_shgrp, facedot_overlay_shgrp, NULL);
-                               }
-                       }
-                       break;
-               case OB_LAMP:
-                       DRW_shgroup_lamp(ob);
-                       break;
-               case OB_CAMERA:
-                       DRW_shgroup_camera(ob);
-                       break;
-               case OB_EMPTY:
-                       DRW_shgroup_empty(ob);
-                       break;
-               case OB_SPEAKER:
-                       DRW_shgroup_speaker(ob);
-                       break;
-               case OB_ARMATURE:
-                       DRW_shgroup_armature_object(ob);
-                       break;
-               default:
-                       break;
-       }
+       if (ob->type == OB_MESH) {
+               if (ob == obedit) {
+                       CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
+                       bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
+                       backwire_opacity = BKE_collection_engine_property_value_get_float(ces_mode_ed, "backwire_opacity"); /* should be done only once */
 
-       DRW_shgroup_object_center(ob);
-       DRW_shgroup_relationship_lines(ob);
-}
+                       face_mod = (do_occlude_wire) ? 0.0f : 1.0f;
 
-void EDIT_MESH_cache_finish(void)
-{
-       /* Do nothing */
+                       if (do_occlude_wire) {
+                               geom = DRW_cache_surface_get(ob);
+                               DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
+                       }
+
+                       if ((v3d->flag & V3D_ZBUF_SELECT) == 0) {
+                               edit_mesh_add_ob_to_pass(scene, ob, face_occluded_shgrp, ledges_occluded_shgrp,
+                                                        lverts_occluded_shgrp, facedot_occluded_shgrp, facefill_occluded_shgrp);
+                       }
+                       else {
+                               edit_mesh_add_ob_to_pass(scene, ob, face_overlay_shgrp, ledges_overlay_shgrp,
+                                                        lverts_overlay_shgrp, facedot_overlay_shgrp, NULL);
+                       }
+               }
+       }
 }
 
-void EDIT_MESH_draw(void)
+static void EDIT_MESH_draw_scene(void)
 {
-       EDIT_MESH_PassList *psl = DRW_mode_pass_list_get();
-       EDIT_MESH_FramebufferList *fbl = DRW_mode_framebuffer_list_get();
-       DefaultFramebufferList *dfbl = DRW_engine_framebuffer_list_get();
-       DefaultTextureList *dtxl = DRW_engine_texture_list_get();
+       EDIT_MESH_Data *vedata = DRW_viewport_engine_data_get("EditMeshMode");
+       EDIT_MESH_PassList *psl = vedata->psl;
+       EDIT_MESH_FramebufferList *fbl = vedata->fbl;
+       DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+       DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
 
        DRW_draw_pass(psl->depth_pass_hidden_wire);
 
@@ -380,10 +352,6 @@ void EDIT_MESH_draw(void)
        else {
                DRW_draw_pass(psl->edit_face_overlay_pass);
        }
-
-       DRW_draw_pass(psl->wire_outline_pass);
-       DRW_draw_pass(psl->non_meshes_pass);
-       DRW_draw_pass(psl->ob_center_pass);
 }
 
 void EDIT_MESH_collection_settings_create(CollectionEngineSettings *ces)
@@ -393,7 +361,7 @@ void EDIT_MESH_collection_settings_create(CollectionEngineSettings *ces)
        BKE_collection_engine_property_add_float(ces, "backwire_opacity", 0.5);
 }
 
-void EDIT_MESH_engine_free(void)
+static void EDIT_MESH_engine_free(void)
 {
        if (overlay_tri_sh)
                DRW_shader_free(overlay_tri_sh);
@@ -415,4 +383,16 @@ void EDIT_MESH_engine_free(void)
                DRW_shader_free(overlay_mix_sh);
        if (overlay_facefill_sh)
                DRW_shader_free(overlay_facefill_sh);
-}
\ No newline at end of file
+}
+
+DrawEngineType draw_engine_edit_mesh_type = {
+       NULL, NULL,
+       N_("EditMeshMode"),
+       &EDIT_MESH_engine_init,
+       &EDIT_MESH_engine_free,
+       &EDIT_MESH_cache_init,
+       &EDIT_MESH_cache_populate,
+       NULL,
+       NULL,
+       &EDIT_MESH_draw_scene
+};
diff --git a/source/blender/draw/modes/edit_mesh_mode.h b/source/blender/draw/modes/edit_mesh_mode.h
deleted file mode 100644 (file)
index 508685b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2016, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Blender Institute
- *
- */
-
-/** \file blender/draw/modes/edit_mesh_mode.h
- *  \ingroup draw
- */
-
-#ifndef __EDIT_MESH_MODE_H__
-#define __EDIT_MESH_MODE_H__
-
-struct Object;
-
-void EDIT_MESH_init(void);
-
-void EDIT_MESH_cache_init(void);
-void EDIT_MESH_cache_populate(struct Object *ob);
-void EDIT_MESH_cache_finish(void);
-
-void EDIT_MESH_draw(void);
-
-void EDIT_MESH_engine_free(void);
-
-#endif /* __EDIT_MESH_MODE_H__ */
\ No newline at end of file
index 25c4bf9..ecfde38 100644 (file)
 #include "DRW_engine.h"
 #include "DRW_render.h"
 
-#include "draw_mode_pass.h"
+#include "DNA_userdef_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_world_types.h"
 
-#include "object_mode.h"
+#include "BKE_camera.h"
+#include "BKE_global.h"
+
+#include "GPU_shader.h"
+
+#include "UI_resources.h"
+
+#include "draw_mode_engines.h"
+#include "draw_common.h"
 
 /* keep it under MAX_PASSES */
 typedef struct OBJECT_PassList {
-       struct DRWPass *non_meshes_pass;
-       struct DRWPass *ob_center_pass;
-       struct DRWPass *wire_outline_pass;
-       struct DRWPass *bone_solid_pass;
-       struct DRWPass *bone_wire_pass;
+       struct DRWPass *non_meshes;
+       struct DRWPass *ob_center;
+       struct DRWPass *wire_outline;
+       struct DRWPass *bone_solid;
+       struct DRWPass *bone_wire;
 } OBJECT_PassList;
 
-void OBJECT_cache_init(void)
+typedef struct OBJECT_Data {
+       char engine_name[32];
+       void *fbl;
+       void *txl;
+       OBJECT_PassList *psl;
+       void *stl;
+} OBJECT_Data;
+
+/* Empties */
+static DRWShadingGroup *plain_axes;
+static DRWShadingGroup *cube;
+static DRWShadingGroup *circle;
+static DRWShadingGroup *sphere;
+static DRWShadingGroup *cone;
+static DRWShadingGroup *single_arrow;
+static DRWShadingGroup *single_arrow_line;
+static DRWShadingGroup *arrows;
+static DRWShadingGroup *axis_names;
+
+/* Speaker */
+static DRWShadingGroup *speaker;
+
+/* Lamps */
+static DRWShadingGroup *lamp_center;
+static DRWShadingGroup *lamp_center_group;
+static DRWShadingGroup *lamp_groundpoint;
+static DRWShadingGroup *lamp_groundline;
+static DRWShadingGroup *lamp_circle;
+static DRWShadingGroup *lamp_circle_shadow;
+static DRWShadingGroup *lamp_sunrays;
+static DRWShadingGroup *lamp_distance;
+static DRWShadingGroup *lamp_buflimit;
+static DRWShadingGroup *lamp_buflimit_points;
+static DRWShadingGroup *lamp_area;
+static DRWShadingGroup *lamp_hemi;
+static DRWShadingGroup *lamp_spot_cone;
+static DRWShadingGroup *lamp_spot_blend;
+static DRWShadingGroup *lamp_spot_pyramid;
+static DRWShadingGroup *lamp_spot_blend_rect;
+
+/* Helpers */
+static DRWShadingGroup *relationship_lines;
+
+/* Objects Centers */
+static DRWShadingGroup *center_active;
+static DRWShadingGroup *center_selected;
+static DRWShadingGroup *center_deselected;
+
+/* Camera */
+static DRWShadingGroup *camera;
+static DRWShadingGroup *camera_tria;
+static DRWShadingGroup *camera_focus;
+static DRWShadingGroup *camera_clip;
+static DRWShadingGroup *camera_clip_points;
+static DRWShadingGroup *camera_mist;
+static DRWShadingGroup *camera_mist_points;
+
+extern GlobalsUboStorage ts;
+
+static OBJECT_Data *vedata;
+
+static void OBJECT_cache_init(void)
+{
+       /* DRW_viewport_engine_data_get is rather slow, better not do it on every objects */
+       vedata = DRW_viewport_engine_data_get("ObjectMode");
+       OBJECT_PassList *psl = vedata->psl;
+
+       {
+               /* This pass can draw mesh outlines and/or fancy wireframe */
+               /* Fancy wireframes are not meant to be occluded (without Z offset) */
+               /* Outlines and Fancy Wires use the same VBO */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+               psl->wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
+       }
+
+       {
+               /* Solid bones */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
+               psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
+       }
+
+       {
+               /* Wire bones */
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
+               psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
+       }
+
+       {
+               /* Non Meshes Pass (Camera, empties, lamps ...) */
+               struct Batch *geom;
+
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_POINT;
+               state |= DRW_STATE_WIRE;
+               psl->non_meshes = DRW_pass_create("Non Meshes Pass", state);
+
+               /* Empties */
+               geom = DRW_cache_plain_axes_get();
+               plain_axes = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_cube_get();
+               cube = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_circle_get();
+               circle = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_empty_sphere_get();
+               sphere = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_empty_cone_get();
+               cone = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_arrow_get();
+               single_arrow = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_line_get();
+               single_arrow_line = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_arrows_get();
+               arrows = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_axis_names_get();
+               axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
+
+               /* Speaker */
+               geom = DRW_cache_speaker_get();
+               speaker = shgroup_instance(psl->non_meshes, geom);
+
+               /* Camera */
+               geom = DRW_cache_camera_get();
+               camera = shgroup_camera_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_camera_tria_get();
+               camera_tria = shgroup_camera_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_plain_axes_get();
+               camera_focus = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_line_get();
+               camera_clip = shgroup_distance_lines_instance(psl->non_meshes, geom);
+               camera_mist = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_line_endpoints_get();
+               camera_clip_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+               camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+               /* Lamps */
+               /* TODO
+                * for now we create multiple times the same VBO with only lamp center coordinates
+                * but ideally we would only create it once */
+
+               /* start with buflimit because we don't want stipples */
+               geom = DRW_cache_single_line_get();
+               lamp_buflimit = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+               lamp_center = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorLampNoAlpha, &ts.sizeLampCenter);
+               lamp_center_group = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorGroup, &ts.sizeLampCenter);
+
+               geom = DRW_cache_lamp_get();
+               lamp_circle = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
+               lamp_circle_shadow = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircleShadow);
+
+               geom = DRW_cache_lamp_sunrays_get();
+               lamp_sunrays = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
+
+               lamp_groundline = shgroup_groundlines_uniform_color(psl->non_meshes, ts.colorLamp);
+               lamp_groundpoint = shgroup_groundpoints_uniform_color(psl->non_meshes, ts.colorLamp);
+
+               geom = DRW_cache_lamp_area_get();
+               lamp_area = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_lamp_hemi_get();
+               lamp_hemi = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_line_get();
+               lamp_distance = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_single_line_endpoints_get();
+               lamp_buflimit_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_lamp_spot_get();
+               lamp_spot_cone = shgroup_spot_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_circle_get();
+               lamp_spot_blend = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_lamp_spot_square_get();
+               lamp_spot_pyramid = shgroup_instance(psl->non_meshes, geom);
+
+               geom = DRW_cache_square_get();
+               lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom);
+
+               /* Relationship Lines */
+               relationship_lines = shgroup_dynlines_uniform_color(psl->non_meshes, ts.colorWire);
+               DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
+       }
+
+       {
+               /* Object Center pass grouped by State */
+               DRWShadingGroup *grp;
+               static float outlineWidth, size;
+
+               DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
+               psl->ob_center = DRW_pass_create("Obj Center Pass", state);
+
+               outlineWidth = 1.0f * U.pixelsize;
+               size = U.obcenter_dia * U.pixelsize + outlineWidth;
+
+               struct GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+
+               /* Active */
+               grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+               DRW_shgroup_uniform_float(grp, "size", &size, 1);
+               DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
+               DRW_shgroup_uniform_vec4(grp, "color", ts.colorActive, 1);
+               DRW_shgroup_uniform_vec4(grp, "outlineColor", ts.colorOutline, 1);
+               center_active = grp;
+
+               /* Select */
+               grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+               DRW_shgroup_uniform_vec4(grp, "color", ts.colorSelect, 1);
+               center_selected = grp;
+
+               /* Deselect */
+               grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
+               DRW_shgroup_uniform_vec4(grp, "color", ts.colorDeselect, 1);
+               center_deselected = grp;
+       }
+}
+
+static void DRW_shgroup_wire_outline(Object *ob, const bool do_wire, const bool do_outline)
+{
+       struct GPUShader *sh;
+       OBJECT_PassList *psl = vedata->psl;
+       struct Batch *geom = DRW_cache_wire_outline_get(ob);
+
+       float *color;
+       DRW_object_wire_theme_get(ob, &color);
+
+       bool is_perps = DRW_viewport_is_persp_get();
+       static bool bTrue = true;
+       static bool bFalse = false;
+
+       /* Note (TODO) : this requires cache to be discarded on ortho/perp switch
+        * It may be preferable (or not depending on performance implication)
+        * to introduce a shader uniform switch */
+       if (is_perps) {
+               sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+       }
+       else {
+               sh = GPU_shader_get_builtin_shader(GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+       }
+
+       if (do_wire) {
+               bool *bFront = (do_wire) ? &bTrue : &bFalse;
+               bool *bBack = (do_wire) ? &bTrue : &bFalse;
+
+               DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->wire_outline);
+               DRW_shgroup_state_set(grp, DRW_STATE_WIRE);
+               DRW_shgroup_uniform_vec4(grp, "frontColor", color, 1);
+               DRW_shgroup_uniform_vec4(grp, "backColor", color, 1);
+               DRW_shgroup_uniform_bool(grp, "drawFront", bFront, 1);
+               DRW_shgroup_uniform_bool(grp, "drawBack", bBack, 1);
+               DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bFalse, 1);
+               DRW_shgroup_call_add(grp, geom, ob->obmat);
+       }
+
+       if (do_outline) {
+               DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->wire_outline);
+               DRW_shgroup_state_set(grp, DRW_STATE_WIRE_LARGE);
+               DRW_shgroup_uniform_vec4(grp, "silhouetteColor", color, 1);
+               DRW_shgroup_uniform_bool(grp, "drawFront", &bFalse, 1);
+               DRW_shgroup_uniform_bool(grp, "drawBack", &bFalse, 1);
+               DRW_shgroup_uniform_bool(grp, "drawSilhouette", &bTrue, 1);
+
+               DRW_shgroup_call_add(grp, geom, ob->obmat);
+       }
+}
+
+static void DRW_shgroup_lamp(Object *ob)
 {
-       OBJECT_PassList *psl = DRW_mode_pass_list_get();
-
-       DRW_mode_passes_setup(NULL,
-                             NULL,
-                             &psl->wire_outline_pass,
-                             &psl->non_meshes_pass,
-                             &psl->ob_center_pass,
-                             &psl->bone_solid_pass,
-                             &psl->bone_wire_pass);
+       Lamp *la = ob->data;
+       float *color;
+       int theme_id = DRW_object_wire_theme_get(ob, &color);
+       static float zero = 0.0f;
+
+       /* Don't draw the center if it's selected or active */
+       if (theme_id == TH_GROUP)
+               DRW_shgroup_dynamic_call_add(lamp_center_group, ob->obmat[3]);
+       else if (theme_id == TH_LAMP)
+               DRW_shgroup_dynamic_call_add(lamp_center, ob->obmat[3]);
+
+       /* First circle */
+       DRW_shgroup_dynamic_call_add(lamp_circle, ob->obmat[3], color);
+
+       /* 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))) {
+                       DRW_shgroup_dynamic_call_add(lamp_circle_shadow, ob->obmat[3], color);
+               }
+       }
+
+       /* Distance */
+       if (ELEM(la->type, LA_HEMI, LA_SUN, LA_AREA)) {
+               DRW_shgroup_dynamic_call_add(lamp_distance, color, &zero, &la->dist, ob->obmat);
+       }
+
+       copy_m4_m4(la->shapemat, ob->obmat);
+
+       if (la->type == LA_SUN) {
+               DRW_shgroup_dynamic_call_add(lamp_sunrays, ob->obmat[3], color);
+       }
+       else if (la->type == LA_SPOT) {
+               float size[3], sizemat[4][4];
+               static float one = 1.0f;
+               float blend = 1.0f - pow2f(la->spotblend);
+
+               size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist;
+               size[2] = cosf(la->spotsize * 0.5f) * la->dist;
+
+               size_to_mat4(sizemat, size);
+               mul_m4_m4m4(la->spotconemat, 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);
+
+               if (la->mode & LA_SQUARE) {
+                       DRW_shgroup_dynamic_call_add(lamp_spot_pyramid,    color, &one, la->spotconemat);
+
+                       /* 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(lamp_spot_blend_rect, color, &one, la->spotblendmat);
+                       }
+               }
+               else {
+                       DRW_shgroup_dynamic_call_add(lamp_spot_cone,  color, la->spotconemat);
+
+                       /* 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(lamp_spot_blend, color, &one, la->spotblendmat);
+                       }
+               }
+
+               normalize_m4(la->shapemat);
+               DRW_shgroup_dynamic_call_add(lamp_buflimit,        color, &la->clipsta, &la->clipend, ob->obmat);
+               DRW_shgroup_dynamic_call_add(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(lamp_hemi, color, &hemisize, la->shapemat);
+       }
+       else if (la->type == LA_AREA) {
+               float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
+
+               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);
+               }
+
+               DRW_shgroup_dynamic_call_add(lamp_area, color, &la->area_size, la->shapemat);
+       }
+
+       /* Line and point going to the ground */
+       DRW_shgroup_dynamic_call_add(lamp_groundline, ob->obmat[3]);
+       DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]);
 }
 
-void OBJECT_cache_populate(Object *ob)
+static void DRW_shgroup_camera(Object *ob)
 {
+       const struct bContext *C = DRW_get_context();
+       View3D *v3d = CTX_wm_view3d(C);
+       Scene *scene = CTX_data_scene(C);
+
+       Camera *cam = ob->data;
+       const bool is_active = (ob == v3d->camera);
+       float *color;
+       DRW_object_wire_theme_get(ob, &color);
+
+       float vec[4][3], asp[2], shift[2], scale[3], drawsize;
+
+       scale[0] = 1.0f / len_v3(ob->obmat[0]);
+       scale[1] = 1.0f / len_v3(ob->obmat[1]);
+       scale[2] = 1.0f / len_v3(ob->obmat[2]);
+
+       BKE_camera_view_frame_ex(scene, cam, cam->drawsize, false, scale,
+                                asp, shift, &drawsize, vec);
+
+       // /* Frame coords */
+       copy_v2_v2(cam->drwcorners[0], vec[0]);
+       copy_v2_v2(cam->drwcorners[1], vec[1]);
+       copy_v2_v2(cam->drwcorners[2], vec[2]);
+       copy_v2_v2(cam->drwcorners[3], vec[3]);
+
+       /* depth */
+       cam->drwdepth = vec[0][2];
+
+       /* tria */
+       cam->drwtria[0][0] = shift[0] + ((0.7f * drawsize) * scale[0]);
+       cam->drwtria[0][1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
+       cam->drwtria[1][0] = shift[0];
+       cam->drwtria[1][1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
+
+       DRW_shgroup_dynamic_call_add(camera, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
+
+       /* Active cam */
+       if (is_active) {
+               DRW_shgroup_dynamic_call_add(camera_tria, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
+       }
+
+       /* draw the rest in normalize object space */
+       copy_m4_m4(cam->drwnormalmat, ob->obmat);
+       normalize_m4(cam->drwnormalmat);
+
+       if (cam->flag & CAM_SHOWLIMITS) {
+               static float col[3] = {0.5f, 0.5f, 0.25f}, col_hi[3] = {1.0f, 1.0f, 0.5f};
+               float sizemat[4][4], size[3] = {1.0f, 1.0f, 0.0f};
+               float focusdist = BKE_camera_object_dof_distance(ob);
+
+               copy_m4_m4(cam->drwfocusmat, cam->drwnormalmat);
+               translate_m4(cam->drwfocusmat, 0.0f, 0.0f, -focusdist);
+               size_to_mat4(sizemat, size);
+               mul_m4_m4m4(cam->drwfocusmat, cam->drwfocusmat, sizemat);
+
+               DRW_shgroup_dynamic_call_add(camera_focus, (is_active ? col_hi : col), &cam->drawsize, cam->drwfocusmat);
+
+               DRW_shgroup_dynamic_call_add(camera_clip, color, &cam->clipsta, &cam->clipend, cam->drwnormalmat);
+               DRW_shgroup_dynamic_call_add(camera_clip_points, (is_active ? col_hi : col), &cam->clipsta, &cam->clipend, cam->drwnormalmat);
+       }
+
+       if (cam->flag & CAM_SHOWMIST) {
+               World *world = scene->world;
+
+               if (world) {
+                       static float col[3] = {0.5f, 0.5f, 0.5f}, col_hi[3] = {1.0f, 1.0f, 1.0f};
+                       world->mistend = world->miststa + world->mistdist;
+                       DRW_shgroup_dynamic_call_add(camera_mist,        color, &world->miststa, &world->mistend, cam->drwnormalmat);
+                       DRW_shgroup_dynamic_call_add(camera_mist_points, (is_active ? col_hi : col), &world->miststa, &world->mistend, cam->drwnormalmat);
+               }
+       }
+}
+
+static void DRW_shgroup_empty(Object *ob)
+{
+       float *color;
+       DRW_object_wire_theme_get(ob, &color);
+
+       switch (ob->empty_drawtype) {
+               case OB_PLAINAXES:
+                       DRW_shgroup_dynamic_call_add(plain_axes, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_SINGLE_ARROW:
+                       DRW_shgroup_dynamic_call_add(single_arrow, color, &ob->empty_drawsize, ob->obmat);
+                       DRW_shgroup_dynamic_call_add(single_arrow_line, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_CUBE:
+                       DRW_shgroup_dynamic_call_add(cube, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_CIRCLE:
+                       DRW_shgroup_dynamic_call_add(circle, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_EMPTY_SPHERE:
+                       DRW_shgroup_dynamic_call_add(sphere, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_EMPTY_CONE:
+                       DRW_shgroup_dynamic_call_add(cone, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+               case OB_ARROWS:
+                       DRW_shgroup_dynamic_call_add(arrows, color, &ob->empty_drawsize, ob->obmat);
+                       DRW_shgroup_dynamic_call_add(axis_names, color, &ob->empty_drawsize, ob->obmat);
+                       break;
+       }
+}
+
+static void DRW_shgroup_speaker(Object *ob)
+{
+       float *color;
+       static float one = 1.0f;
+       DRW_object_wire_theme_get(ob, &color);
+
+       DRW_shgroup_dynamic_call_add(speaker, color, &one, ob->obmat);
+}
+
+static void DRW_shgroup_relationship_lines(Object *ob)
+{
+       if (ob->parent) {
+               DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]);
+               DRW_shgroup_dynamic_call_add(relationship_lines, ob->parent->obmat[3]);
+       }
+}
+
+static void DRW_shgroup_object_center(Object *ob)
+{
+       if ((ob->base_flag & BASE_SELECTED) != 0) {
+               DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);
+       }
+       else if (0) {
+               DRW_shgroup_dynamic_call_add(center_deselected, ob->obmat[3]);
+       }
+}
+
+static void OBJECT_cache_populate(Object *ob)
+{
+       const struct bContext *C = DRW_get_context();
+       Scene *scene = CTX_data_scene(C);
+
        CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
 
        bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
@@ -61,7 +570,12 @@ void OBJECT_cache_populate(Object *ob)
 
        switch (ob->type) {
                case OB_MESH:
-                       DRW_shgroup_wire_outline(ob, do_wire, false, do_outlines);
+                       {
+                               Object *obedit = scene->obedit;
+                               if (ob != obedit) {
+                                       DRW_shgroup_wire_outline(ob, do_wire, do_outlines);
+                               }
+                       }
                        break;
                case OB_LAMP:
                        DRW_shgroup_lamp(ob);
@@ -76,7 +590,14 @@ void OBJECT_cache_populate(Object *ob)
                        DRW_shgroup_speaker(ob);
                        break;
                case OB_ARMATURE:
-                       DRW_shgroup_armature_object(ob);
+                       {
+                               bArmature *arm = ob->data;
+                               if (arm->edbo == NULL) {
+                                       DRW_shgroup_armature_object(ob, vedata->psl->bone_solid,
+                                                                       vedata->psl->bone_wire,
+                                                                       relationship_lines);
+                               }
+                       }
                        break;
                default:
                        break;
@@ -86,20 +607,16 @@ void OBJECT_cache_populate(Object *ob)
        DRW_shgroup_relationship_lines(ob);
 }
 
-void OBJECT_cache_finish(void)
+static void OBJECT_draw_scene(void)
 {
-       /* Do nothing */
-}
-
-void OBJECT_draw(void)
-{
-       OBJECT_PassList *psl = DRW_mode_pass_list_get();
+       OBJECT_Data *ved = DRW_viewport_engine_data_get("ObjectMode");
+       OBJECT_PassList *psl = ved->psl;
 
-       DRW_draw_pass(psl->bone_wire_pass);
-       DRW_draw_pass(psl->bone_solid_pass);
-       DRW_draw_pass(psl->wire_outline_pass);
-       DRW_draw_pass(psl->non_meshes_pass);
-       DRW_draw_pass(psl->ob_center_pass);
+       DRW_draw_pass(psl->bone_wire);
+       DRW_draw_pass(psl->bone_solid);
+       DRW_draw_pass(psl->wire_outline);
+       DRW_draw_pass(psl->non_meshes);
+       DRW_draw_pass(psl->ob_center);
 }
 
 void OBJECT_collection_settings_create(CollectionEngineSettings *ces)
@@ -108,3 +625,15 @@ void OBJECT_collection_settings_create(CollectionEngineSettings *ces)
        BKE_collection_engine_property_add_int(ces, "show_wire", false);
        BKE_collection_engine_property_add_int(ces, "show_backface_culling", false);
 }
+
+DrawEngineType draw_engine_object_type = {
+       NULL, NULL,
+       N_("ObjectMode"),
+       NULL,
+       NULL,
+       &OBJECT_cache_init,
+       &OBJECT_cache_populate,
+       NULL,
+       NULL,
+       &OBJECT_draw_scene
+};
index f6d5cf6..34b68a8 100644 (file)
@@ -25,6 +25,7 @@ set(INC
        ../../blenlib
        ../../blentranslation
        ../../bmesh
+       ../../draw
        ../../gpu
        ../../imbuf
        ../../makesdna
index f41d7d6..21d0776 100644 (file)
@@ -60,6 +60,8 @@
 #include "DNA_view3d_types.h"
 #include "DNA_windowmanager_types.h"
 
+#include "DRW_engine.h"
+
 #include "ED_keyframing.h"
 #include "ED_armature.h"
 #include "ED_keyframing.h"
@@ -2330,34 +2332,18 @@ static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data
 #endif
 }
 
-static void view3d_render_pass(const bContext *C, ARegion *UNUSED(ar))
-{
-       Scene *scene = CTX_data_scene(C);
-       RenderEngineType *type = RE_engines_find(scene->r.engine); /* In the future we should get that from Layers */
-
-       if (type->flag & RE_USE_OGL_PIPELINE) {
-               type->view_draw(NULL, C);
-       }
-       else {
-               // Offline Render engine
-       }
-}
-
 static void view3d_draw_view_new(const bContext *C, ARegion *ar, DrawData *UNUSED(draw_data))
 {
-
        view3d_draw_setup_view(C, ar);
 
        /* Only 100% compliant on new spec goes bellow */
-       view3d_render_pass(C, ar);
+       DRW_draw_view(C);
 }
 
-
 void view3d_main_region_draw(const bContext *C, ARegion *ar)
 {
        Scene *scene = CTX_data_scene(C);
        View3D *v3d = CTX_wm_view3d(C);
-       int mode = CTX_data_mode_enum(C);
        RegionView3D *rv3d = ar->regiondata;
        /* TODO layers - In the future we should get RE from Layers */
        RenderEngineType *type = RE_engines_find(scene->r.engine);
@@ -2370,21 +2356,19 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
        if (!rv3d->viewport)
                rv3d->viewport = GPU_viewport_create();
 
-       GPU_viewport_bind(rv3d->viewport, &ar->winrct, scene->r.engine, mode);
-
        /* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
         * before we even call the drawing routine, but let's move on for now (dfelinto)
         * but this is a provisory way to start seeing things in the viewport */
        DrawData draw_data;
        view3d_draw_data_init(C, ar, rv3d, &draw_data);
 
+       GPU_viewport_bind(rv3d->viewport, &ar->winrct);
+
        if (type->flag & RE_USE_OGL_PIPELINE)
                view3d_draw_view_new(C, ar, &draw_data);
        else
                view3d_draw_view(C, ar, &draw_data);
 
-       GPU_viewport_unbind(rv3d->viewport);
-
        v3d->flag |= V3D_INVALID_BACKBUF;
 }
 
index f0e991f..64f003b 100644 (file)
@@ -63,28 +63,27 @@ typedef struct StorageList {
        void *storage[MAX_STORAGE]; /* custom structs from the engine */
 } StorageList;
 
-/* Buffer and textures used by the viewport by default */
-typedef struct DefaultFramebufferList {
-       struct GPUFrameBuffer *default_fb;
-} DefaultFramebufferList;
+typedef struct ViewportEngineData {
+       char engine_name[32];
 
-typedef struct DefaultTextureList {
-       struct GPUTexture *color;
-       struct GPUTexture *depth;
-} DefaultTextureList;
-
-typedef struct DefaultPassList {
-       struct DRWPass *non_meshes_pass;
-       struct DRWPass *ob_center_pass;
-} DefaultPassList;
+       FramebufferList *fbl;
+       TextureList *txl;
+       PassList *psl;
+       StorageList *stl;
+} ViewportEngineData;
 
 GPUViewport *GPU_viewport_create(void);
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode);
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect);
 void GPU_viewport_unbind(GPUViewport *viewport);
 void GPU_viewport_free(GPUViewport *viewport);
 
-void GPU_viewport_get_engine_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str);
-void GPU_viewport_get_mode_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str);
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, const char *engine_name);
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, const char *engine_name);
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport);
+void *GPU_viewport_texture_list_get(GPUViewport *viewport);
+void  GPU_viewport_size_get(GPUViewport *viewport, int *size);
+
+bool GPU_viewport_cache_validate(GPUViewport *viewport, int hash);
 
 /* debug */
 bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);
index c8e60c0..fc5c3ce 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <string.h>
 
+#include "BLI_listbase.h"
 #include "BLI_rect.h"
 #include "BLI_string.h"
 
@@ -57,20 +58,11 @@ struct GPUViewport {
        GPUTexture *debug_depth;
        int size[2];
 
-       /* Viewport Buffer Storage */
+       ListBase data;  /* ViewportEngineData wrapped in LinkData */
+       int data_hash;  /* If hash mismatch we free all ViewportEngineData in this viewport */
+
        FramebufferList *fbl;
        TextureList *txl;
-       PassList *psl;
-       StorageList *stl;
-
-       char engine_name[32];
-
-       /* Mode storage */
-       FramebufferList *fbl_mode;
-       TextureList *txl_mode;
-       PassList *psl_mode;
-       StorageList *stl_mode;
-       int mode;
 };
 
 static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl);
@@ -82,66 +74,118 @@ GPUViewport *GPU_viewport_create(void)
        GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
        viewport->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
        viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList");
-       viewport->psl = MEM_callocN(sizeof(PassList), "PassList");
-       viewport->stl = MEM_callocN(sizeof(StorageList), "StorageList");
-       viewport->fbl_mode = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
-       viewport->txl_mode = MEM_callocN(sizeof(TextureList), "TextureList");
-       viewport->psl_mode = MEM_callocN(sizeof(PassList), "PassList");
-       viewport->stl_mode = MEM_callocN(sizeof(StorageList), "StorageList");
        viewport->size[0] = viewport->size[1] = -1;
 
        return viewport;
 }
 
-void GPU_viewport_get_engine_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
+void *GPU_viewport_engine_data_create(GPUViewport *viewport, const char *engine_name)
 {
-       *fbs = viewport->fbl;
-       *txs = viewport->txl;
-       *pss = viewport->psl;
-       *str = viewport->stl;
+       LinkData *ld = MEM_callocN(sizeof(LinkData), "LinkData");
+       ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData");
+       BLI_strncpy(data->engine_name, engine_name, 32);
+
+       data->fbl = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
+       data->txl = MEM_callocN(sizeof(TextureList), "TextureList");
+       data->psl = MEM_callocN(sizeof(PassList), "PassList");
+       data->stl = MEM_callocN(sizeof(StorageList), "StorageList");
+
+       ld->data = data;
+       BLI_addtail(&viewport->data, ld);
+
+       return data;
 }
 
-void GPU_viewport_get_mode_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
+static void GPU_viewport_engines_data_free(GPUViewport *viewport)
 {
-       *fbs = viewport->fbl_mode;
-       *txs = viewport->txl_mode;
-       *pss = viewport->psl_mode;
-       *str = viewport->stl_mode;
+       LinkData *next;
+       for (LinkData *link = viewport->data.first; link; link = next) {
+               next = link->next;
+               ViewportEngineData *data = link->data;
+
+               GPU_viewport_buffers_free(data->fbl, data->txl);
+               GPU_viewport_passes_free(data->psl);
+               GPU_viewport_storage_free(data->stl);
+
+               MEM_freeN(data->fbl);
+               MEM_freeN(data->txl);
+               MEM_freeN(data->psl);
+               MEM_freeN(data->stl);
+
+               MEM_freeN(data);
+
+               BLI_remlink(&viewport->data, link);
+               MEM_freeN(link);
+       }
 }
 
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode)
+void *GPU_viewport_engine_data_get(GPUViewport *viewport, const char *engine_name)
 {
-       DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
-       DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
+       for (LinkData *link = viewport->data.first; link; link = link->next) {
+               ViewportEngineData *vdata = link->data;
+               if (STREQ(engine_name, vdata->engine_name)) {
+                       return vdata;
+               }
+       }
+       return NULL;
+}
 
-       /* add one pixel because of scissor test */
-       int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
+void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport)
+{
+       return viewport->fbl;
+}
+
+void *GPU_viewport_texture_list_get(GPUViewport *viewport)
+{
+       return viewport->txl;
+}
+
+void GPU_viewport_size_get(GPUViewport *viewport, int *size)
+{
+       size[0] = viewport->size[0];
+       size[1] = viewport->size[1];
+}
 
+bool GPU_viewport_cache_validate(GPUViewport *viewport, int hash)
+{
+       bool dirty = false;
+
+       /* TODO for testing only, we need proper cache invalidation */
        if (G.debug_value != 666 && G.debug_value != 667) {
-               /* TODO for testing only, we need proper cache invalidation */
-               GPU_viewport_passes_free(viewport->psl);
-               GPU_viewport_passes_free(viewport->psl_mode);
+               for (LinkData *link = viewport->data.first; link; link = link->next) {
+                       ViewportEngineData *data = link->data;
+                       GPU_viewport_passes_free(data->psl);
+               }
+               dirty = true;
        }
 
-       if (!STREQ(engine, viewport->engine_name)) {
-               GPU_viewport_storage_free(viewport->stl);
-               GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
-
-               BLI_strncpy(viewport->engine_name, engine, 32);
+       if (viewport->data_hash != hash) {
+               GPU_viewport_engines_data_free(viewport);
+               dirty = true;
        }
 
-       if (mode != viewport->mode) {
-               GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
-               GPU_viewport_passes_free(viewport->psl_mode);
-               GPU_viewport_storage_free(viewport->stl_mode);
+       viewport->data_hash = hash;
 
-               viewport->mode = mode;
-       }
+       return dirty;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect)
+{
+       DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
+       DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
+
+       /* add one pixel because of scissor test */
+       int rect_w = BLI_rcti_size_x(rect) + 1;
+       int rect_h = BLI_rcti_size_y(rect) + 1;
 
        if (dfbl->default_fb) {
                if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
                        GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
-                       GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
+
+                       for (LinkData *link = viewport->data.first; link; link = link->next) {
+                               ViewportEngineData *data = link->data;
+                               GPU_viewport_buffers_free(data->fbl, data->txl);
+                       }
                }
        }
 
@@ -211,12 +255,11 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
        unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
 
        immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
-
        GPU_texture_bind(color, 0);
 
        immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
 
-       immBegin(GL_QUADS, 4);
+       immBegin(GL_TRIANGLE_STRIP, 4);
 
        immAttrib2f(texcoord, 0.0f, 0.0f);
        immVertex2f(pos, 0.0f, 0.0f);
@@ -224,12 +267,12 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
        immAttrib2f(texcoord, 1.0f, 0.0f);
        immVertex2f(pos, w, 0.0f);
 
-       immAttrib2f(texcoord, 1.0f, 1.0f);
-       immVertex2f(pos, w, h);
-
        immAttrib2f(texcoord, 0.0f, 1.0f);
        immVertex2f(pos, 0.0f, h);
 
+       immAttrib2f(texcoord, 1.0f, 1.0f);
+       immVertex2f(pos, w, h);
+
        immEnd();
 
        GPU_texture_unbind(color);
@@ -296,25 +339,13 @@ static void GPU_viewport_passes_free(PassList *psl)
 
 void GPU_viewport_free(GPUViewport *viewport)
 {
-       GPU_viewport_debug_depth_free(viewport);
+       GPU_viewport_engines_data_free(viewport);
 
        GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
-       GPU_viewport_passes_free(viewport->psl);
-       GPU_viewport_storage_free(viewport->stl);
-
-       GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
-       GPU_viewport_passes_free(viewport->psl_mode);
-       GPU_viewport_storage_free(viewport->stl_mode);
-
        MEM_freeN(viewport->fbl);
        MEM_freeN(viewport->txl);
-       MEM_freeN(viewport->psl);
-       MEM_freeN(viewport->stl);
 
-       MEM_freeN(viewport->fbl_mode);
-       MEM_freeN(viewport->txl_mode);
-       MEM_freeN(viewport->psl_mode);
-       MEM_freeN(viewport->stl_mode);
+       GPU_viewport_debug_depth_free(viewport);
 }
 
 /****************** debug ********************/
@@ -360,7 +391,7 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con
        immUniform1f("zfar", zfar);
        immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
 
-       immBegin(GL_QUADS, 4);
+       immBegin(GL_TRIANGLE_STRIP, 4);
 
        immAttrib2f(texcoord, 0.0f, 0.0f);
        immVertex2f(pos, 0.0f, 0.0f);
@@ -368,12 +399,12 @@ void GPU_viewport_debug_depth_draw(GPUViewport *viewport, const float znear, con
        immAttrib2f(texcoord, 1.0f, 0.0f);
        immVertex2f(pos, w, 0.0f);
 
-       immAttrib2f(texcoord, 1.0f, 1.0f);
-       immVertex2f(pos, w, h);
-
        immAttrib2f(texcoord, 0.0f, 1.0f);
        immVertex2f(pos, 0.0f, h);
 
+       immAttrib2f(texcoord, 1.0f, 1.0f);
+       immVertex2f(pos, w, h);
+
        immEnd();
 
        GPU_texture_unbind(viewport->debug_depth);
index f1b3534..74d96ce 100644 (file)
@@ -102,6 +102,8 @@ typedef struct RenderEngineType {
 
        void (*collection_settings_create)(struct RenderEngine *engine, struct CollectionEngineSettings *ces);
 
+       struct DrawEngineType *draw_engine;
+
        /* RNA integration */
        ExtensionRNA ext;
 } RenderEngineType;
index 1744d88..8c1cdb3 100644 (file)
@@ -71,7 +71,7 @@
 static RenderEngineType internal_render_type = {
        NULL, NULL,
        "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        {NULL, NULL, NULL}
 };
 
@@ -80,7 +80,7 @@ static RenderEngineType internal_render_type = {
 static RenderEngineType internal_game_type = {
        NULL, NULL,
        "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME,
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        {NULL, NULL, NULL}
 };
 
@@ -94,7 +94,7 @@ void RE_engines_init(void)
 #ifdef WITH_GAMEENGINE
        RE_engines_register(NULL, &internal_game_type);
 #endif
-       DRW_engines_init();
+       DRW_engines_register();
 }
 
 void RE_engines_exit(void)
@@ -121,6 +121,9 @@ void RE_engines_exit(void)
 
 void RE_engines_register(Main *bmain, RenderEngineType *render_type)
 {
+       if (render_type->draw_engine) {
+               DRW_engine_register(render_type->draw_engine);
+       }
        if (render_type->collection_settings_create) {
                BKE_layer_collection_engine_settings_callback_register(bmain, render_type->idname, render_type->collection_settings_create);
        }