diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-02-17 19:29:43 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-02-17 19:30:15 +0300 |
commit | 50fb3ea3de8db278fd135392b990158b745e3e3f (patch) | |
tree | 1a7ebdd585605bc70c56c0791b6a8ee4584459ca /source | |
parent | 9cb44cbba13817dc981e4d865ec04847f03fb719 (diff) |
Clay Engine: Separate mode drawing to different files/engines.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/blender/draw/engines/clay/clay.c | 301 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 17 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 141 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_mode_pass.c | 124 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_mode_pass.h | 21 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_mode.c | 107 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_mode.h | 35 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 91 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.h | 35 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 3 | ||||
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 7 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 120 |
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 ********************/ |