Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/CMakeLists.txt5
-rw-r--r--source/blender/draw/engines/clay/clay.c301
-rw-r--r--source/blender/draw/intern/DRW_render.h17
-rw-r--r--source/blender/draw/intern/draw_manager.c141
-rw-r--r--source/blender/draw/intern/draw_mode_pass.c124
-rw-r--r--source/blender/draw/intern/draw_mode_pass.h21
-rw-r--r--source/blender/draw/modes/edit_mode.c107
-rw-r--r--source/blender/draw/modes/edit_mode.h35
-rw-r--r--source/blender/draw/modes/object_mode.c91
-rw-r--r--source/blender/draw/modes/object_mode.h35
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c3
-rw-r--r--source/blender/gpu/GPU_viewport.h7
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c120
13 files changed, 714 insertions, 293 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 006fb0fbc23..be517d799a5 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -27,6 +27,7 @@ set(INC
.
intern
engines/clay
+ modes/
../blenkernel
../blenlib
@@ -55,12 +56,16 @@ set(SRC
intern/draw_cache.c
intern/draw_view.c
engines/clay/clay.c
+ modes/edit_mode.c
+ modes/object_mode.c
intern/DRW_render.h
intern/draw_mode_pass.h
intern/draw_cache.h
intern/draw_view.h
engines/clay/clay.h
+ modes/edit_mode.h
+ modes/object_mode.h
./DRW_engine.h
)
diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c
index 1673dd219c0..f121eb8600e 100644
--- a/source/blender/draw/engines/clay/clay.c
+++ b/source/blender/draw/engines/clay/clay.c
@@ -126,17 +126,9 @@ enum {
/* keep it under MAX_PASSES */
typedef struct CLAY_PassList{
- /* default */
- struct DRWPass *non_meshes_pass;
- struct DRWPass *ob_center_pass;
- /* engine specific */
struct DRWPass *depth_pass;
struct DRWPass *depth_pass_cull;
- struct DRWPass *depth_pass_hidden_wire;
struct DRWPass *clay_pass;
- struct DRWPass *wire_overlay_pass;
- struct DRWPass *wire_outline_pass;
- struct DRWPass *wire_outline_pass_hidden_wire;
} CLAY_PassList;
//#define GTAO
@@ -286,8 +278,12 @@ MaterialEngineSettings *CLAY_material_settings_create(void)
return (MaterialEngineSettings *)settings;
}
-static void CLAY_engine_init(CLAY_StorageList *stl, CLAY_TextureList *txl, CLAY_FramebufferList *fbl)
+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();
+
/* Create Texture Array */
if (!data.matcap_array) {
PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
@@ -384,56 +380,56 @@ static void CLAY_engine_init(CLAY_StorageList *stl, CLAY_TextureList *txl, CLAY_
(int)viewport_size[0], (int)viewport_size[1],
&tex, 1);
}
-}
-static void CLAY_ssao_setup(void)
-{
- float invproj[4][4];
- float dfdyfacs[2];
- bool is_persp = DRW_viewport_is_persp_get();
- /* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
- float viewvecs[3][4] = {
- {-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f}
- };
- int i;
- float *size = DRW_viewport_size_get();
- RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
-
- DRW_get_dfdy_factors(dfdyfacs);
-
- data.ssao_params[0] = settings->ssao_samples;
- data.ssao_params[1] = size[0] / 64.0;
- data.ssao_params[2] = size[1] / 64.0;
- data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
-
- /* invert the view matrix */
- DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
- invert_m4_m4(invproj, data.winmat);
-
- /* convert the view vectors to view space */
- for (i = 0; i < 3; i++) {
- mul_m4_v4(invproj, viewvecs[i]);
- /* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
- if (is_persp)
- mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
- viewvecs[i][3] = 1.0;
-
- copy_v4_v4(data.viewvecs[i], viewvecs[i]);
- }
+ /* SSAO setup */
+ {
+ float invproj[4][4];
+ float dfdyfacs[2];
+ bool is_persp = DRW_viewport_is_persp_get();
+ /* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
+ float viewvecs[3][4] = {
+ {-1.0f, -1.0f, -1.0f, 1.0f},
+ {1.0f, -1.0f, -1.0f, 1.0f},
+ {-1.0f, 1.0f, -1.0f, 1.0f}
+ };
+ int i;
+ float *size = DRW_viewport_size_get();
+ RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
+
+ DRW_get_dfdy_factors(dfdyfacs);
+
+ data.ssao_params[0] = settings->ssao_samples;
+ data.ssao_params[1] = size[0] / 64.0;
+ data.ssao_params[2] = size[1] / 64.0;
+ data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
+
+ /* invert the view matrix */
+ DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
+ invert_m4_m4(invproj, data.winmat);
+
+ /* convert the view vectors to view space */
+ for (i = 0; i < 3; i++) {
+ mul_m4_v4(invproj, viewvecs[i]);
+ /* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
+ if (is_persp)
+ mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
+ viewvecs[i][3] = 1.0;
+
+ copy_v4_v4(data.viewvecs[i], viewvecs[i]);
+ }
- /* we need to store the differences */
- data.viewvecs[1][0] -= data.viewvecs[0][0];
- data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
+ /* we need to store the differences */
+ data.viewvecs[1][0] -= data.viewvecs[0][0];
+ data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
- /* calculate a depth offset as well */
- if (!is_persp) {
- float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
- mul_m4_v4(invproj, vec_far);
- mul_v3_fl(vec_far, 1.0f / vec_far[3]);
- data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2];
+ /* calculate a depth offset as well */
+ if (!is_persp) {
+ float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
+ mul_m4_v4(invproj, vec_far);
+ mul_v3_fl(vec_far, 1.0f / vec_far[3]);
+ data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2];
+ }
}
}
@@ -605,112 +601,104 @@ static DRWShadingGroup *CLAY_object_shgrp_get(Object *ob, CLAY_StorageList *stl,
return shgrps[id];
}
-static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, const struct bContext *C)
+static DRWShadingGroup *depth_shgrp;
+static DRWShadingGroup *depth_shgrp_cull;
+
+static void CLAY_cache_init(void)
{
- SceneLayer *sl = CTX_data_scene_layer(C);
- DRWShadingGroup *clay_shgrp;
- DRWShadingGroup *depth_shgrp;
- DRWShadingGroup *depth_shgrp_cull;
- DRWShadingGroup *depth_shgrp_hidden_wire;
+ CLAY_PassList *psl = DRW_engine_pass_list_get();
+ CLAY_StorageList *stl = DRW_engine_storage_list_get();
+
/* Depth Pass */
{
- passes->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
- depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, passes->depth_pass_cull);
- passes->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- depth_shgrp = DRW_shgroup_create(data.depth_sh, passes->depth_pass);
- passes->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
- depth_shgrp_hidden_wire = DRW_shgroup_create(data.depth_sh, passes->depth_pass_hidden_wire);
+ psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
+ depth_shgrp = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
}
/* Clay Pass */
{
- passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
+ psl->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
stl->storage->ubo_current_id = 0;
memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
}
+}
- /* Object Mode */
- {
- DRW_pass_setup_common(&passes->wire_overlay_pass,
- &passes->wire_outline_pass,
- &passes->wire_outline_pass_hidden_wire,
- &passes->non_meshes_pass,
- &passes->ob_center_pass);
- }
+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();
+ struct Batch *geom;
+ DRWShadingGroup *clay_shgrp;
+ bool do_occlude_wire = false;
+ bool do_cull = false;
+ CollectionEngineSettings *ces_mode_ed, *ces_mode_ob;
- /* TODO Create hash table of batch based on material id*/
- DEG_OBJECT_ITER(sl, ob);
- {
- if ((ob->base_flag & BASE_VISIBLED) == 0) {
- continue;
- }
+ if ((ob->base_flag & BASE_VISIBLED) == 0)
+ return;
- CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
- CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
-
- struct Batch *geom;
- bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
- bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
- bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
- bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0) || do_wire;
-
- switch (ob->type) {
- case OB_MESH:
- geom = DRW_cache_surface_get(ob);
-
- /* Depth Prepass */
- if (do_occlude_wire)
- DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
- else
- DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
-
- /* Shading */
- if (!do_occlude_wire) {
- clay_shgrp = CLAY_object_shgrp_get(ob, stl, passes);
- DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
- }
-
- //DRW_shgroup_wire_overlay(passes->wire_overlay_pass, ob);
-
- /* Wires / Outlines */
- if (do_occlude_wire) {
- DRW_shgroup_wire_outline(passes->wire_outline_pass_hidden_wire, ob, true, false, true);
- }
- else {
- DRW_shgroup_wire_outline(passes->wire_outline_pass, ob, do_wire, false, do_outlines);
- }
-
- break;
- case OB_LAMP:
- case OB_CAMERA:
- case OB_EMPTY:
- default:
- DRW_shgroup_non_meshes(passes->non_meshes_pass, ob);
- break;
- }
+ 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)
+ return;
+
+ switch (ob->type) {
+ case OB_MESH:
+ geom = DRW_cache_surface_get(ob);
- DRW_shgroup_object_center(passes->ob_center_pass, ob);
- DRW_shgroup_relationship_lines(passes->non_meshes_pass, ob);
+ /* 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);
+ break;
}
- DEG_OBJECT_ITER_END
+}
+
+static void CLAY_cache_finish(void)
+{
+ CLAY_StorageList *stl = DRW_engine_storage_list_get();
DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
}
static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
{
+ DRW_viewport_init(context);
+
/* This function may run for multiple viewports
* so get the current viewport buffers */
- CLAY_FramebufferList *buffers = NULL;
- CLAY_TextureList *textures = NULL;
- CLAY_PassList *passes = NULL;
- CLAY_StorageList *storage = NULL;
-
- DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes, (void **)&storage);
-
- CLAY_engine_init(storage, textures, buffers);
+ CLAY_PassList *psl = DRW_engine_pass_list_get();
+ CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
+ CLAY_engine_init();
/* TODO : tag to refresh by the deps graph */
/* ideally only refresh when objects are added/removed */
@@ -726,38 +714,39 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
#ifdef WITH_VIEWPORT_CACHE_TEST
once = true;
#endif
- CLAY_create_cache(passes, storage, context);
+ 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();
/* Pass 1 : Depth pre-pass */
- DRW_draw_pass(passes->depth_pass);
- DRW_draw_pass(passes->depth_pass_cull);
+ DRW_draw_pass(psl->depth_pass);
+ DRW_draw_pass(psl->depth_pass_cull);
/* Pass 2 : Duplicate depth */
/* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
- DRW_framebuffer_blit(buffers->default_fb, buffers->dupli_depth, true);
+ DRW_framebuffer_blit(fbl->default_fb, fbl->dupli_depth, true);
/* Pass 3 : Shading */
- CLAY_ssao_setup();
- DRW_draw_pass(passes->clay_pass);
+ DRW_draw_pass(psl->clay_pass);
/* Pass 4 : Overlays */
- DRW_draw_grid();
- //DRW_draw_pass(passes->wire_overlay_pass);
- DRW_draw_pass(passes->wire_outline_pass);
- DRW_draw_pass(passes->non_meshes_pass);
-
- /* Hidden Wires */
- DRW_draw_pass(passes->depth_pass_hidden_wire);
- DRW_draw_pass(passes->wire_outline_pass_hidden_wire);
-
- DRW_draw_pass(passes->ob_center_pass);
-
- DRW_draw_manipulator();
- DRW_draw_region_info();
+ /* At this point all shaded geometry should have been rendered and their depth written */
+ DRW_draw_mode_overlays();
/* Always finish by this */
DRW_state_reset();
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ae278b612fc..83e48a02d1b 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -197,7 +197,7 @@ typedef enum {
DRW_MAT_WIN,
} DRWViewportMatrixType;
-void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage);
+void DRW_viewport_init(const bContext *C);
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
float *DRW_viewport_size_get(void);
float *DRW_viewport_screenvecs_get(void);
@@ -211,13 +211,26 @@ 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_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_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__ */ \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index c265f57297f..283be353e8e 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -53,6 +53,8 @@
#include "UI_resources.h"
+#include "object_mode.h"
+#include "edit_mode.h"
#include "clay.h"
#define MAX_ATTRIB_NAME 32
@@ -159,9 +161,10 @@ enum {
static struct DRWGlobalState{
GPUShader *shader;
struct GPUFrameBuffer *default_framebuffer;
- FramebufferList *current_fbl;
- TextureList *current_txl;
- PassList *current_psl;
+ FramebufferList *fbl, *fbl_mode;
+ TextureList *txl, *txl_mode;
+ PassList *psl, *psl_mode;
+ StorageList *stl, *stl_mode;
ListBase bound_texs;
int tex_bind_id;
float size[2];
@@ -852,15 +855,15 @@ static void draw_shgroup(DRWShadingGroup *shgroup)
break;
case DRW_UNIFORM_BUFFER:
/* restore index from lenght we abused */
- GPU_texture_bind(DST.current_txl->textures[uni->length], uni->bindloc);
- GPU_texture_compare_mode(DST.current_txl->textures[uni->length], false);
- GPU_texture_filter_mode(DST.current_txl->textures[uni->length], false);
+ GPU_texture_bind(DST.txl->textures[uni->length], uni->bindloc);
+ GPU_texture_compare_mode(DST.txl->textures[uni->length], false);
+ GPU_texture_filter_mode(DST.txl->textures[uni->length], false);
bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
- bound_tex->tex = DST.current_txl->textures[uni->length];
+ bound_tex->tex = DST.txl->textures[uni->length];
BLI_addtail(&DST.bound_texs, bound_tex);
- GPU_shader_uniform_texture(shgroup->shader, uni->location, DST.current_txl->textures[uni->length]);
+ GPU_shader_uniform_texture(shgroup->shader, uni->location, DST.txl->textures[uni->length]);
break;
case DRW_UNIFORM_BLOCK:
GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
@@ -1013,7 +1016,74 @@ void DRW_state_reset(void)
state |= DRW_STATE_DEPTH_LESS;
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_draw();
+ break;
+ case CTX_MODE_OBJECT:
+ OBJECT_draw();
+ break;
+ }
+
+ DRW_draw_manipulator();
+ DRW_draw_region_info();
+}
#endif
+
+/* ******************************************* Mode Engine Cache ****************************************** */
+void DRW_mode_cache_init(void)
+{
+ const bContext *C = DRW_get_context();
+ int mode = CTX_data_mode_enum(C);
+
+ switch (mode) {
+ case CTX_MODE_EDIT_MESH:
+ EDIT_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_cache_populate(ob);
+ break;
+ case CTX_MODE_OBJECT:
+ OBJECT_cache_populate(ob);
+ break;
+ }
+}
+
+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_cache_finish();
+ break;
+ case CTX_MODE_OBJECT:
+ OBJECT_cache_finish();
+ break;
+ }
+}
+
/* ****************************************** Settings ******************************************/
void *DRW_material_settings_get(Material *ma, const char *engine_name)
{
@@ -1155,25 +1225,22 @@ float *DRW_viewport_pixelsize_get(void)
return &DST.pixsize;
}
-void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage)
+void DRW_viewport_init(const bContext *C)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
GPUViewport *viewport = rv3d->viewport;
- GPU_viewport_get_engine_data(viewport, buffers, textures, passes, storage);
+ 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 *)*textures;
+ DefaultTextureList *txl = (DefaultTextureList *)DST.txl;
DST.size[0] = (float)GPU_texture_width(txl->color);
DST.size[1] = (float)GPU_texture_height(txl->color);
- DefaultFramebufferList *fbl = (DefaultFramebufferList *)*buffers;
+ DefaultFramebufferList *fbl = (DefaultFramebufferList *)DST.fbl;
DST.default_framebuffer = fbl->default_fb;
- DST.current_txl = (TextureList *)*textures;
- DST.current_fbl = (FramebufferList *)*buffers;
- DST.current_psl = (PassList *)*passes;
-
/* Refresh DST.screenvecs */
copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
@@ -1208,7 +1275,7 @@ bool DRW_viewport_is_persp_get(void)
bool DRW_viewport_cache_is_dirty(void)
{
/* TODO Use a dirty flag */
- return (DST.current_psl->passes[0] == NULL);
+ return (DST.psl->passes[0] == NULL);
}
/* ****************************************** OTHER ***************************************** */
@@ -1218,6 +1285,46 @@ const bContext *DRW_get_context(void)
return DST.context;
}
+void *DRW_engine_pass_list_get(void)
+{
+ return DST.psl;
+}
+
+void *DRW_engine_storage_list_get(void)
+{
+ return DST.stl;
+}
+
+void *DRW_engine_texture_list_get(void)
+{
+ return DST.txl;
+}
+
+void *DRW_engine_framebuffer_list_get(void)
+{
+ return DST.fbl;
+}
+
+void *DRW_mode_pass_list_get(void)
+{
+ return DST.psl_mode;
+}
+
+void *DRW_mode_storage_list_get(void)
+{
+ return DST.stl_mode;
+}
+
+void *DRW_mode_texture_list_get(void)
+{
+ return DST.txl_mode;
+}
+
+void *DRW_mode_framebuffer_list_get(void)
+{
+ return DST.fbl_mode;
+}
+
/* ****************************************** INIT ***************************************** */
void DRW_engines_init(void)
diff --git a/source/blender/draw/intern/draw_mode_pass.c b/source/blender/draw/intern/draw_mode_pass.c
index 32a9417735d..08fba9479c1 100644
--- a/source/blender/draw/intern/draw_mode_pass.c
+++ b/source/blender/draw/intern/draw_mode_pass.c
@@ -76,6 +76,13 @@ static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], c
static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
+/* 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 DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
{
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -160,9 +167,13 @@ static DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
}
/* This Function setup the passes needed for the mode rendering.
- * The passes are populated by the rendering engine using the DRW_shgroup_* functions. */
-void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **wire_outline_pass_hidden_wire,
- DRWPass **non_meshes, DRWPass **ob_center)
+ * 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)
{
UI_GetThemeColor4fv(TH_WIRE, colorWire);
UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit);
@@ -179,67 +190,65 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
colorLampNoAlpha[3] = 1.0f;
- if (wire_overlay) {
+ 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;
- *wire_overlay = DRW_pass_create("Wire Overlays Pass", state);
+ *psl_wire_overlay = DRW_pass_create("Wire Overlays Pass", state);
}
- if (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 */
+ 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_LESS | DRW_STATE_BLEND;
- *wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
+ *psl_wire_overlay_hidden_wire = DRW_pass_create("Wire Overlays Pass", state);
}
- if (wire_outline_pass_hidden_wire) {
+ 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;
- *wire_outline_pass_hidden_wire = DRW_pass_create("Wire + Outlines Pass", state);
+ *psl_wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
}
- if (non_meshes) {
+ 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;
state |= DRW_STATE_WIRE;
- *non_meshes = DRW_pass_create("Non Meshes Pass", state);
+ *psl_non_meshes = DRW_pass_create("Non Meshes Pass", state);
/* Empties */
geom = DRW_cache_plain_axes_get();
- plain_axes = shgroup_instance(*non_meshes, geom);
+ plain_axes = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_cube_get();
- cube = shgroup_instance(*non_meshes, geom);
+ cube = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_circle_get();
- circle = shgroup_instance(*non_meshes, geom);
+ circle = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_empty_sphere_get();
- sphere = shgroup_instance(*non_meshes, geom);
+ sphere = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_empty_cone_get();
- cone = shgroup_instance(*non_meshes, geom);
+ cone = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_single_arrow_get();
- single_arrow = shgroup_instance(*non_meshes, geom);
+ single_arrow = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_single_line_get();
- single_arrow_line = shgroup_instance(*non_meshes, geom);
+ single_arrow_line = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_arrows_get();
- arrows = shgroup_instance(*non_meshes, geom);
+ arrows = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_axis_names_get();
- axis_names = shgroup_instance_axis_names(*non_meshes, geom);
+ axis_names = shgroup_instance_axis_names(*psl_non_meshes, geom);
/* Speaker */
geom = DRW_cache_speaker_get();
- speaker = shgroup_instance(*non_meshes, geom);
+ speaker = shgroup_instance(*psl_non_meshes, geom);
/* Lamps */
lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize;
@@ -248,32 +257,32 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
/* TODO
* for now we create 3 times the same VBO with only lamp center coordinates
* but ideally we would only create it once */
- lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize);
- lamp_center_group = shgroup_dynpoints_uniform_color(*non_meshes, colorGroup, &lampCenterSize);
+ lamp_center = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorLampNoAlpha, &lampCenterSize);
+ lamp_center_group = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorGroup, &lampCenterSize);
geom = DRW_cache_lamp_get();
- lamp_circle = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleRad);
- lamp_circle_shadow = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleShadowRad);
+ lamp_circle = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleRad);
+ lamp_circle_shadow = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleShadowRad);
geom = DRW_cache_lamp_sunrays_get();
- lamp_sunrays = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleRad);
+ lamp_sunrays = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleRad);
- lamp_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp);
- lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp);
+ lamp_groundline = shgroup_groundlines_uniform_color(*psl_non_meshes, colorLamp);
+ lamp_groundpoint = shgroup_groundpoints_uniform_color(*psl_non_meshes, colorLamp);
/* Relationship Lines */
- relationship_lines = shgroup_dynlines_uniform_color(*non_meshes, colorWire);
+ relationship_lines = shgroup_dynlines_uniform_color(*psl_non_meshes, colorWire);
DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
}
- if (ob_center) {
+ if (psl_ob_center) {
/* Object Center pass grouped by State */
DRWShadingGroup *grp;
static float colorDeselect[4], outlineColor[4];
static float outlineWidth, size;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
- *ob_center = DRW_pass_create("Obj Center Pass", state);
+ *psl_ob_center = DRW_pass_create("Obj Center Pass", state);
outlineWidth = 1.0f * U.pixelsize;
size = U.obcenter_dia * U.pixelsize + outlineWidth;
@@ -285,7 +294,7 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH);
/* Active */
- grp = DRW_shgroup_point_batch_create(sh, *ob_center);
+ 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", colorActive, 1);
@@ -293,15 +302,22 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
center_active = grp;
/* Select */
- grp = DRW_shgroup_point_batch_create(sh, *ob_center);
+ grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
DRW_shgroup_uniform_vec4(grp, "color", colorSelect, 1);
center_selected = grp;
/* Deselect */
- grp = DRW_shgroup_point_batch_create(sh, *ob_center);
+ grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
DRW_shgroup_uniform_vec4(grp, "color", 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;
}
/* ******************************************** WIRES *********************************************** */
@@ -373,7 +389,7 @@ static int draw_object_wire_theme(Object *ob, float **color)
return theme_id;
}
-void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
+void DRW_shgroup_wire_overlay(Object *ob)
{
#if 1
struct Batch *geom = DRW_cache_wire_overlay_get(ob);
@@ -395,8 +411,7 @@ void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
#endif
}
-void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
- const bool do_front, const bool do_back, const bool do_outline)
+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);
@@ -459,7 +474,7 @@ void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
/* ***************************** NON MESHES ********************** */
-static void DRW_draw_lamp(Object *ob)
+void DRW_shgroup_lamp(Object *ob)
{
Lamp *la = ob->data;
float *color;
@@ -489,7 +504,7 @@ static void DRW_draw_lamp(Object *ob)
DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]);
}
-static void DRW_draw_empty(Object *ob)
+void DRW_shgroup_empty(Object *ob)
{
float *color;
draw_object_wire_theme(ob, &color);
@@ -517,12 +532,11 @@ static void DRW_draw_empty(Object *ob)
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);
- /* TODO Missing axes names */
break;
}
}
-static void DRW_draw_speaker(Object *ob)
+void DRW_shgroup_speaker(Object *ob)
{
float *color;
static float one = 1.0f;
@@ -531,25 +545,7 @@ static void DRW_draw_speaker(Object *ob)
DRW_shgroup_dynamic_call_add(speaker, color, &one, ob->obmat);
}
-void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), Object *ob)
-{
- switch (ob->type) {
- case OB_LAMP:
- DRW_draw_lamp(ob);
- break;
- case OB_CAMERA:
- case OB_EMPTY:
- DRW_draw_empty(ob);
- break;
- case OB_SPEAKER:
- DRW_draw_speaker(ob);
- break;
- default:
- break;
- }
-}
-
-void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
+void DRW_shgroup_relationship_lines(Object *ob)
{
if (ob->parent) {
DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]);
@@ -559,7 +555,7 @@ void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
/* ***************************** COMMON **************************** */
-void DRW_shgroup_object_center(DRWPass *UNUSED(ob_center), Object *ob)
+void DRW_shgroup_object_center(Object *ob)
{
if ((ob->base_flag & BASE_SELECTED) != 0) {
DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);
diff --git a/source/blender/draw/intern/draw_mode_pass.h b/source/blender/draw/intern/draw_mode_pass.h
index b0fd3e69bd7..c0d66cef347 100644
--- a/source/blender/draw/intern/draw_mode_pass.h
+++ b/source/blender/draw/intern/draw_mode_pass.h
@@ -30,15 +30,18 @@ struct DRWPass;
struct Batch;
struct Object;
-void DRW_pass_setup_common(struct DRWPass **wire_overlay, struct DRWPass **wire_outline, struct DRWPass **wire_outline_pass_hidden_wire,
- struct DRWPass **non_meshes, struct DRWPass **ob_center);
+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);
-void DRW_shgroup_wire_overlay(struct DRWPass *wire_overlay, struct Object *ob);
-void DRW_shgroup_wire_outline(
- struct DRWPass *wire_outline, struct Object *ob, const bool do_front, const bool do_back, const bool do_outline);
-
-void DRW_shgroup_non_meshes(struct DRWPass *non_meshes, struct Object *ob);
-void DRW_shgroup_relationship_lines(struct DRWPass *non_meshes, struct Object *ob);
-void DRW_shgroup_object_center(struct DRWPass *ob_center, struct Object *ob);
+void DRW_shgroup_wire_overlay(struct Object *ob);
+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_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);
#endif /* __DRAW_MODE_PASS_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/modes/edit_mode.c b/source/blender/draw/modes/edit_mode.c
new file mode 100644
index 00000000000..83c9cdd1901
--- /dev/null
+++ b/source/blender/draw/modes/edit_mode.c
@@ -0,0 +1,107 @@
+/*
+ * 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_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_render.h"
+
+#include "draw_mode_pass.h"
+
+#include "edit_mode.h"
+
+/* keep it under MAX_PASSES */
+typedef struct EDIT_PassList{
+ struct DRWPass *non_meshes_pass;
+ struct DRWPass *ob_center_pass;
+ struct DRWPass *wire_outline_pass;
+ struct DRWPass *depth_pass_hidden_wire;
+} EDIT_PassList;
+
+static DRWShadingGroup *depth_shgrp_hidden_wire;
+
+void EDIT_cache_init(void)
+{
+ EDIT_PassList *psl = DRW_mode_pass_list_get();
+ static struct GPUShader *depth_sh;
+
+ if (!depth_sh) {
+ depth_sh = DRW_shader_create_3D_depth_only();
+ }
+
+ psl->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
+ depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_pass_hidden_wire);
+
+ DRW_mode_passes_setup(NULL,
+ NULL,
+ &psl->wire_outline_pass,
+ &psl->non_meshes_pass,
+ &psl->ob_center_pass);
+}
+
+void EDIT_cache_populate(Object *ob)
+{
+ 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");
+
+ switch (ob->type) {
+ case OB_MESH:
+ geom = DRW_cache_surface_get(ob);
+ if (do_occlude_wire) {
+ DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
+ DRW_shgroup_wire_outline(ob, true, false, true);
+ }
+ break;
+ case OB_LAMP:
+ DRW_shgroup_lamp(ob);
+ break;
+ case OB_CAMERA:
+ case OB_EMPTY:
+ DRW_shgroup_empty(ob);
+ break;
+ case OB_SPEAKER:
+ DRW_shgroup_speaker(ob);
+ break;
+ default:
+ break;
+ }
+
+ DRW_shgroup_object_center(ob);
+ DRW_shgroup_relationship_lines(ob);
+}
+
+void EDIT_cache_finish(void)
+{
+ /* Do nothing */
+}
+
+void EDIT_draw(void)
+{
+ EDIT_PassList *psl = DRW_mode_pass_list_get();
+
+ DRW_draw_pass(psl->depth_pass_hidden_wire);
+ DRW_draw_pass(psl->wire_outline_pass);
+ DRW_draw_pass(psl->non_meshes_pass);
+ DRW_draw_pass(psl->ob_center_pass);
+} \ No newline at end of file
diff --git a/source/blender/draw/modes/edit_mode.h b/source/blender/draw/modes/edit_mode.h
new file mode 100644
index 00000000000..241450ac2b3
--- /dev/null
+++ b/source/blender/draw/modes/edit_mode.h
@@ -0,0 +1,35 @@
+/*
+ * 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_mode.c
+ * \ingroup draw
+ */
+
+#ifndef __EDIT_MODE_H__
+#define __EDIT_MODE_H__
+
+void EDIT_cache_init(void);
+void EDIT_cache_populate(Object *ob);
+void EDIT_cache_finish(void);
+
+void EDIT_draw(void);
+
+#endif /* __EDIT_MODE_H__ */ \ No newline at end of file
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
new file mode 100644
index 00000000000..2b553ffcdbc
--- /dev/null
+++ b/source/blender/draw/modes/object_mode.c
@@ -0,0 +1,91 @@
+/*
+ * 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/object_mode.c
+ * \ingroup draw
+ */
+
+#include "DRW_render.h"
+
+#include "draw_mode_pass.h"
+
+#include "object_mode.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;
+} OBJECT_PassList;
+
+void OBJECT_cache_init(void)
+{
+ 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);
+}
+
+void OBJECT_cache_populate(Object *ob)
+{
+ 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");
+ bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0) || do_wire;
+
+ switch (ob->type) {
+ case OB_MESH:
+ DRW_shgroup_wire_outline(ob, do_wire, false, do_outlines);
+ break;
+ case OB_LAMP:
+ DRW_shgroup_lamp(ob);
+ break;
+ case OB_CAMERA:
+ case OB_EMPTY:
+ DRW_shgroup_empty(ob);
+ break;
+ case OB_SPEAKER:
+ DRW_shgroup_speaker(ob);
+ break;
+ default:
+ break;
+ }
+
+ DRW_shgroup_object_center(ob);
+ DRW_shgroup_relationship_lines(ob);
+}
+
+void OBJECT_cache_finish(void)
+{
+ /* Do nothing */
+}
+
+void OBJECT_draw(void)
+{
+ OBJECT_PassList *psl = DRW_mode_pass_list_get();
+
+ DRW_draw_pass(psl->wire_outline_pass);
+ DRW_draw_pass(psl->non_meshes_pass);
+ DRW_draw_pass(psl->ob_center_pass);
+} \ No newline at end of file
diff --git a/source/blender/draw/modes/object_mode.h b/source/blender/draw/modes/object_mode.h
new file mode 100644
index 00000000000..7cd66d608e7
--- /dev/null
+++ b/source/blender/draw/modes/object_mode.h
@@ -0,0 +1,35 @@
+/*
+ * 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/object_mode.h
+ * \ingroup draw
+ */
+
+#ifndef __OBJECT_MODE_H__
+#define __OBJECT_MODE_H__
+
+void OBJECT_cache_init(void);
+void OBJECT_cache_populate(Object *ob);
+void OBJECT_cache_finish(void);
+
+void OBJECT_draw(void);
+
+#endif /* __OBJECT_MODE_H__ */ \ No newline at end of file
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1a5ec33d3fc..fe4574f2fda 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2356,6 +2356,7 @@ 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);
@@ -2368,7 +2369,7 @@ 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);
+ 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)
diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h
index 9de16f64ca1..f0e991fdac2 100644
--- a/source/blender/gpu/GPU_viewport.h
+++ b/source/blender/gpu/GPU_viewport.h
@@ -56,7 +56,7 @@ typedef struct TextureList {
} TextureList;
typedef struct PassList {
- struct DRWPass *passes[MAX_TEXTURES];
+ struct DRWPass *passes[MAX_PASSES];
} PassList;
typedef struct StorageList {
@@ -79,11 +79,12 @@ typedef struct DefaultPassList {
} DefaultPassList;
GPUViewport *GPU_viewport_create(void);
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine);
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode);
void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_free(GPUViewport *viewport);
-void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str);
+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);
/* debug */
bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 62ba06b7a0a..a189f6770a0 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -56,18 +56,24 @@ struct GPUViewport {
int size[2];
/* Viewport Buffer Storage */
- /* TODO indentify to what engine conf are theses buffers */
- DefaultFramebufferList *fbl;
- DefaultTextureList *txl;
- DefaultPassList *psl;
+ 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(GPUViewport *viewport);
-static void GPU_viewport_passes_free(GPUViewport *viewport);
-static void GPU_viewport_storage_free(GPUViewport *viewport);
+static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl);
+static void GPU_viewport_storage_free(StorageList *stl);
+static void GPU_viewport_passes_free(PassList *psl);
GPUViewport *GPU_viewport_create(void)
{
@@ -76,12 +82,16 @@ GPUViewport *GPU_viewport_create(void)
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, void **fbs, void **txs, void **pss, void **str)
+void GPU_viewport_get_engine_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
{
*fbs = viewport->fbl;
*txs = viewport->txl;
@@ -89,64 +99,85 @@ void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs,
*str = viewport->stl;
}
-void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine)
+void GPU_viewport_get_mode_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
+{
+ *fbs = viewport->fbl_mode;
+ *txs = viewport->txl_mode;
+ *pss = viewport->psl_mode;
+ *str = viewport->stl_mode;
+}
+
+void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode)
{
+ 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, rect_h = BLI_rcti_size_y(rect) + 1;
#ifndef WITH_VIEWPORT_CACHE_TEST
/* TODO for testing only, we need proper cache invalidation */
- GPU_viewport_passes_free(viewport);
+ GPU_viewport_passes_free(viewport->psl);
+ GPU_viewport_passes_free(viewport->psl_mode);
#endif
if (!STREQ(engine, viewport->engine_name)) {
- GPU_viewport_storage_free(viewport);
- GPU_viewport_buffers_free(viewport);
+ GPU_viewport_storage_free(viewport->stl);
+ GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
BLI_strncpy(viewport->engine_name, engine, 32);
}
- if (viewport->fbl->default_fb) {
+ 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->mode = mode;
+ }
+
+ if (dfbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
- GPU_viewport_buffers_free(viewport);
+ GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
+ GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
}
}
- if (!viewport->fbl->default_fb) {
+ if (!dfbl->default_fb) {
bool ok = true;
viewport->size[0] = rect_w;
viewport->size[1] = rect_h;
- viewport->fbl->default_fb = GPU_framebuffer_create();
- if (!viewport->fbl->default_fb) {
+ dfbl->default_fb = GPU_framebuffer_create();
+ if (!dfbl->default_fb) {
ok = false;
goto cleanup;
}
/* Color */
/* No multi samples for now */
- viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
- if (!viewport->txl->color) {
+ dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
+ if (!dtxl->color) {
ok = false;
goto cleanup;
}
- if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) {
+ if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->color, 0)) {
ok = false;
goto cleanup;
}
/* Depth */
- viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
- if (!viewport->txl->depth) {
+ dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
+ if (!dtxl->depth) {
ok = false;
goto cleanup;
}
- else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) {
+ else if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0)) {
ok = false;
goto cleanup;
}
- else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) {
+ else if (!GPU_framebuffer_check_valid(dfbl->default_fb, NULL)) {
ok = false;
goto cleanup;
}
@@ -161,12 +192,14 @@ cleanup:
GPU_framebuffer_restore();
}
- GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0);
+ GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
}
static void draw_ofs_to_screen(GPUViewport *viewport)
{
- GPUTexture *color = viewport->txl->color;
+ DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
+
+ GPUTexture *color = dtxl->color;
const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color);
@@ -204,7 +237,9 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
void GPU_viewport_unbind(GPUViewport *viewport)
{
- if (viewport->fbl->default_fb) {
+ DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
+
+ if (dfbl->default_fb) {
GPU_framebuffer_texture_unbind(NULL, NULL);
GPU_framebuffer_restore();
@@ -215,10 +250,8 @@ void GPU_viewport_unbind(GPUViewport *viewport)
}
}
-static void GPU_viewport_buffers_free(GPUViewport *viewport)
+static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl)
{
- FramebufferList *fbl = (FramebufferList *)viewport->fbl;
- TextureList *txl = (TextureList *)viewport->txl;
int i;
for (i = MAX_BUFFERS - 1; i > -1; --i) {
GPUFrameBuffer *fb = fbl->framebuffers[i];
@@ -236,10 +269,8 @@ static void GPU_viewport_buffers_free(GPUViewport *viewport)
}
}
-static void GPU_viewport_storage_free(GPUViewport *viewport)
+static void GPU_viewport_storage_free(StorageList *stl)
{
- StorageList *stl = (StorageList *)viewport->stl;
-
for (int i = MAX_STORAGE - 1; i > -1; --i) {
void *storage = stl->storage[i];
if (storage) {
@@ -249,12 +280,9 @@ static void GPU_viewport_storage_free(GPUViewport *viewport)
}
}
-static void GPU_viewport_passes_free(GPUViewport *viewport)
+static void GPU_viewport_passes_free(PassList *psl)
{
- PassList *psl = (PassList *)viewport->psl;
- int i;
-
- for (i = MAX_PASSES - 1; i > -1; --i) {
+ for (int i = MAX_PASSES - 1; i > -1; --i) {
struct DRWPass *pass = psl->passes[i];
if (pass) {
DRW_pass_free(pass);
@@ -267,14 +295,24 @@ static void GPU_viewport_passes_free(GPUViewport *viewport)
void GPU_viewport_free(GPUViewport *viewport)
{
GPU_viewport_debug_depth_free(viewport);
- GPU_viewport_buffers_free(viewport);
- GPU_viewport_passes_free(viewport);
- GPU_viewport_storage_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);
}
/****************** debug ********************/