Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/modes/edit_metaball_mode.c
| Show All 20 Lines | |||||
| /** \file blender/draw/modes/edit_metaball_mode.c | /** \file blender/draw/modes/edit_metaball_mode.c | ||||
| * \ingroup draw | * \ingroup draw | ||||
| */ | */ | ||||
| #include "DRW_engine.h" | #include "DRW_engine.h" | ||||
| #include "DRW_render.h" | #include "DRW_render.h" | ||||
| #include "DNA_meta_types.h" | |||||
| #include "BKE_mball.h" | |||||
| /* If builtin shaders are needed */ | /* If builtin shaders are needed */ | ||||
| #include "GPU_shader.h" | #include "GPU_shader.h" | ||||
| #include "GPU_select.h" | |||||
| #include "draw_common.h" | #include "draw_common.h" | ||||
| #include "draw_mode_engines.h" | #include "draw_mode_engines.h" | ||||
| /* If needed, contains all global/Theme colors | /* If needed, contains all global/Theme colors | ||||
| * Add needed theme colors / values to DRW_globals_update() and update UBO | * Add needed theme colors / values to DRW_globals_update() and update UBO | ||||
| * Not needed for constant color. */ | * Not needed for constant color. */ | ||||
| Show All 27 Lines | typedef struct EDIT_METABALL_TextureList { | ||||
| struct GPUTexture *texture; | struct GPUTexture *texture; | ||||
| } EDIT_METABALL_TextureList; | } EDIT_METABALL_TextureList; | ||||
| typedef struct EDIT_METABALL_StorageList { | typedef struct EDIT_METABALL_StorageList { | ||||
| /* Contains any other memory block that the engine needs. | /* Contains any other memory block that the engine needs. | ||||
| * Only directly MEM_(m/c)allocN'ed blocks because they are | * Only directly MEM_(m/c)allocN'ed blocks because they are | ||||
| * free with MEM_freeN() when viewport is freed. | * free with MEM_freeN() when viewport is freed. | ||||
| * (not per object) */ | * (not per object) */ | ||||
| struct CustomStruct *block; | // struct CustomStruct *block; | ||||
| struct EDIT_METABALL_PrivateData *g_data; | struct EDIT_METABALL_PrivateData *g_data; | ||||
| } EDIT_METABALL_StorageList; | } EDIT_METABALL_StorageList; | ||||
| typedef struct EDIT_METABALL_Data { | typedef struct EDIT_METABALL_Data { | ||||
| /* Struct returned by DRW_viewport_engine_data_get. | /* Struct returned by DRW_viewport_engine_data_get. | ||||
| * If you don't use one of these, just make it a (void *) */ | * If you don't use one of these, just make it a (void *) */ | ||||
| // void *fbl; | // void *fbl; | ||||
| void *engine_type; /* Required */ | void *engine_type; /* Required */ | ||||
| EDIT_METABALL_FramebufferList *fbl; | EDIT_METABALL_FramebufferList *fbl; | ||||
| EDIT_METABALL_TextureList *txl; | EDIT_METABALL_TextureList *txl; | ||||
| EDIT_METABALL_PassList *psl; | EDIT_METABALL_PassList *psl; | ||||
| EDIT_METABALL_StorageList *stl; | EDIT_METABALL_StorageList *stl; | ||||
| } EDIT_METABALL_Data; | } EDIT_METABALL_Data; | ||||
| /* *********** STATIC *********** */ | /* *********** STATIC *********** */ | ||||
| static struct { | |||||
| /* Custom shaders : | |||||
| * Add sources to source/blender/draw/modes/shaders | |||||
| * init in EDIT_METABALL_engine_init(); | |||||
| * free in EDIT_METABALL_engine_free(); */ | |||||
| struct GPUShader *custom_shader; | |||||
| } e_data = {NULL}; /* Engine data */ | |||||
| typedef struct EDIT_METABALL_PrivateData { | typedef struct EDIT_METABALL_PrivateData { | ||||
| /* This keeps the references of the shading groups for | /* This keeps the references of the shading groups for | ||||
| * easy access in EDIT_METABALL_cache_populate() */ | * easy access in EDIT_METABALL_cache_populate() */ | ||||
| DRWShadingGroup *group; | DRWShadingGroup *group; | ||||
| } EDIT_METABALL_PrivateData; /* Transient data */ | } EDIT_METABALL_PrivateData; /* Transient data */ | ||||
| /* *********** FUNCTIONS *********** */ | /* *********** FUNCTIONS *********** */ | ||||
| /* Init Textures, Framebuffers, Storage and Shaders. | |||||
| * It is called for every frames. | |||||
| * (Optional) */ | |||||
| static void EDIT_METABALL_engine_init(void *vedata) | |||||
| { | |||||
| EDIT_METABALL_TextureList *txl = ((EDIT_METABALL_Data *)vedata)->txl; | |||||
| EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl; | |||||
| EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | |||||
| UNUSED_VARS(txl, fbl, stl); | |||||
| /* Init Framebuffers like this: order is attachment order (for color texs) */ | |||||
| /* | |||||
| * DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0}, | |||||
| * {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}}; | |||||
| */ | |||||
| /* DRW_framebuffer_init takes care of checking if | |||||
| * the framebuffer is valid and has the right size*/ | |||||
| /* | |||||
| * float *viewport_size = DRW_viewport_size_get(); | |||||
| * DRW_framebuffer_init(&fbl->occlude_wire_fb, | |||||
| * (int)viewport_size[0], (int)viewport_size[1], | |||||
| * tex, 2); | |||||
| */ | |||||
| if (!e_data.custom_shader) { | |||||
| e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); | |||||
| } | |||||
| } | |||||
| /* Here init all passes and shading groups | /* Here init all passes and shading groups | ||||
| * Assume that all Passes are NULL */ | * Assume that all Passes are NULL */ | ||||
| static void EDIT_METABALL_cache_init(void *vedata) | static void EDIT_METABALL_cache_init(void *vedata) | ||||
| { | { | ||||
| EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | ||||
| EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | ||||
| if (!stl->g_data) { | if (!stl->g_data) { | ||||
| /* Alloc transient pointers */ | /* Alloc transient pointers */ | ||||
| stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); | stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); | ||||
| } | } | ||||
| { | { | ||||
| /* Create a pass */ | /* Create a pass */ | ||||
| DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE; | DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE; | ||||
| psl->pass = DRW_pass_create("My Pass", state); | psl->pass = DRW_pass_create("My Pass", state); | ||||
| /* Create a shadingGroup using a function in draw_common.c or custom one */ | /* Create a shadingGroup using a function in draw_common.c or custom one */ | ||||
| /* | stl->g_data->group = shgroup_instance_mball_helpers(psl->pass, DRW_cache_screenspace_circle_get()); | ||||
| * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire); | } | ||||
| * -- or -- | } | ||||
| * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass); | |||||
| */ | static void EDIT_METABALL_cache_populate_radius_visualization( | ||||
| stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass); | DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4], | ||||
| const float *radius, const int selection_id) | |||||
| { | |||||
| const float *color; | |||||
| static const float col_radius[3] = {0.63, 0.19, 0.19}; /* 0x3030A0 */ | |||||
| static const float col_radius_select[3] = {0.94, 0.63, 0.63}; /* 0xA0A0F0 */ | |||||
| /* Uniforms need a pointer to it's value so be sure it's accessible at | if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) color = col_radius_select; | ||||
| * any given time (i.e. use static vars) */ | else color = col_radius; | ||||
| static float color[4] = {0.0f, 1.0f, 0.0f, 1.0}; | |||||
| DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1); | if (selection_id != -1) { | ||||
| ml->selcol1 = selection_id; | |||||
| DRW_select_load_id(selection_id); | |||||
| } | } | ||||
| DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color); | |||||
| } | } | ||||
| /* Add geometry to shadingGroups. Execute for each objects */ | static void EDIT_METABALL_cache_populate_stiffness_visualization( | ||||
| static void EDIT_METABALL_cache_populate(void *vedata, Object *ob) | DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4], | ||||
| const float *radius, const int selection_id) | |||||
| { | { | ||||
| EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | const float *color; | ||||
| EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | static const float col_stiffness[3] = {0.19, 0.63, 0.19}; /* 0x30A030 */ | ||||
| static const float col_stiffness_select[3] = {0.63, 0.94, 0.63}; /* 0xA0F0A0 */ | |||||
| UNUSED_VARS(psl, stl); | |||||
| if (ob->type == OB_MESH) { | if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) color = col_stiffness_select; | ||||
| /* Get geometry cache */ | else color = col_stiffness; | ||||
| struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); | |||||
| /* Add geom to a shading group */ | if (selection_id != -1) { | ||||
| DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat); | ml->selcol2 = selection_id; | ||||
Severin: Clean code 101: Instead of adding such comment you should add a new function. E.g. | |||||
| DRW_select_load_id(selection_id); | |||||
| } | } | ||||
| DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color); | |||||
| } | } | ||||
| /* Optional: Post-cache_populate callback */ | /* Add geometry to shadingGroups. Execute for each objects */ | ||||
| static void EDIT_METABALL_cache_finish(void *vedata) | static void EDIT_METABALL_cache_populate(void *vedata, Object *ob) | ||||
| { | { | ||||
| EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | //EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | ||||
| EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl; | ||||
| /* Do something here! dependant on the objects gathered */ | if (ob->type == OB_MBALL) { | ||||
| UNUSED_VARS(psl, stl); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| Scene *scene = draw_ctx->scene; | |||||
| Object *obedit = scene->obedit; | |||||
| DRWShadingGroup *group = stl->g_data->group; | |||||
| if (ob == obedit) { | |||||
| MetaBall *mb = ob->data; | |||||
| const bool is_select = DRW_state_is_select(); | |||||
| int selection_id = 0; | |||||
| for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) { | |||||
| BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x); | |||||
| ml->draw_stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2; | |||||
| EDIT_METABALL_cache_populate_radius_visualization( | |||||
| group, ml, ml->draw_scale_xform, &ml->rad, is_select ? ++selection_id : -1); | |||||
| EDIT_METABALL_cache_populate_stiffness_visualization( | |||||
| group, ml, ml->draw_scale_xform, &ml->draw_stiffness_radius, is_select ? ++selection_id : -1); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /* Draw time ! Control rendering pipeline from here */ | /* Draw time ! Control rendering pipeline from here */ | ||||
| static void EDIT_METABALL_draw_scene(void *vedata) | static void EDIT_METABALL_draw_scene(void *vedata) | ||||
| { | { | ||||
| EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl; | ||||
| EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl; | /* render passes on default framebuffer. */ | ||||
| /* Default framebuffer and texture */ | |||||
| DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); | |||||
| DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); | |||||
| UNUSED_VARS(fbl, dfbl, dtxl); | |||||
| /* Show / hide entire passes, swap framebuffers ... whatever you fancy */ | |||||
| /* | |||||
| * DRW_framebuffer_texture_detach(dtxl->depth); | |||||
| * DRW_framebuffer_bind(fbl->custom_fb); | |||||
| * DRW_draw_pass(psl->pass); | |||||
| * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0); | |||||
| * DRW_framebuffer_bind(dfbl->default_fb); | |||||
| */ | |||||
| /* ... or just render passes on default framebuffer. */ | |||||
| DRW_draw_pass(psl->pass); | DRW_draw_pass(psl->pass); | ||||
| /* If you changed framebuffer, double check you rebind | /* If you changed framebuffer, double check you rebind | ||||
| * the default one with its textures attached before finishing */ | * the default one with its textures attached before finishing */ | ||||
| } | } | ||||
| /* Cleanup when destroying the engine. | /* Cleanup when destroying the engine. | ||||
| * This is not per viewport ! only when quitting blender. | * This is not per viewport ! only when quitting blender. | ||||
| Show All 25 Lines | |||||
| #endif | #endif | ||||
| static const DrawEngineDataSize EDIT_METABALL_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_METABALL_Data); | static const DrawEngineDataSize EDIT_METABALL_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_METABALL_Data); | ||||
| DrawEngineType draw_engine_edit_metaball_type = { | DrawEngineType draw_engine_edit_metaball_type = { | ||||
| NULL, NULL, | NULL, NULL, | ||||
| N_("EditMetaballMode"), | N_("EditMetaballMode"), | ||||
| &EDIT_METABALL_data_size, | &EDIT_METABALL_data_size, | ||||
| &EDIT_METABALL_engine_init, | NULL, | ||||
| &EDIT_METABALL_engine_free, | &EDIT_METABALL_engine_free, | ||||
| &EDIT_METABALL_cache_init, | &EDIT_METABALL_cache_init, | ||||
| &EDIT_METABALL_cache_populate, | &EDIT_METABALL_cache_populate, | ||||
| &EDIT_METABALL_cache_finish, | NULL, | ||||
| NULL, /* draw_background but not needed by mode engines */ | NULL, /* draw_background but not needed by mode engines */ | ||||
| &EDIT_METABALL_draw_scene, | &EDIT_METABALL_draw_scene, | ||||
| NULL, | NULL, | ||||
| }; | }; | ||||
Clean code 101: Instead of adding such comment you should add a new function. E.g. EDIT_METABALL_cache_populate_radius_visualization.
These functions can also set the static const color variables themselves and limit their scope that way.
Oh, and would also prefer the loop to be a for loop instead, so that you can see how we iterate exactly on first sight :) Also extra NULL check above isn't needed then.