Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/modes/paint_weight_mode.c
| Show All 31 Lines | |||||
| #include "draw_common.h" | #include "draw_common.h" | ||||
| #include "draw_mode_engines.h" | #include "draw_mode_engines.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_view3d_types.h" | #include "DNA_view3d_types.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_colorband.h" | |||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | ||||
| extern struct GlobalsUboStorage ts; /* draw_common.c */ | extern struct GlobalsUboStorage ts; /* draw_common.c */ | ||||
| extern char datatoc_paint_weight_vert_glsl[]; | |||||
| extern char datatoc_paint_weight_frag_glsl[]; | |||||
| extern char datatoc_paint_wire_vert_glsl[]; | extern char datatoc_paint_wire_vert_glsl[]; | ||||
| extern char datatoc_paint_wire_frag_glsl[]; | extern char datatoc_paint_wire_frag_glsl[]; | ||||
| extern char datatoc_paint_vert_frag_glsl[]; | extern char datatoc_paint_vert_frag_glsl[]; | ||||
| extern char datatoc_common_globals_lib_glsl[]; | extern char datatoc_common_globals_lib_glsl[]; | ||||
| /* *********** LISTS *********** */ | /* *********** LISTS *********** */ | ||||
| typedef struct PAINT_WEIGHT_PassList { | typedef struct PAINT_WEIGHT_PassList { | ||||
| struct DRWPass *weight_faces; | struct DRWPass *weight_faces; | ||||
| struct DRWPass *wire_overlay; | struct DRWPass *wire_overlay; | ||||
| struct DRWPass *face_overlay; | struct DRWPass *face_overlay; | ||||
| struct DRWPass *vert_overlay; | struct DRWPass *vert_overlay; | ||||
| } PAINT_WEIGHT_PassList; | } PAINT_WEIGHT_PassList; | ||||
| typedef struct PAINT_WEIGHT_TextureList { | |||||
| struct GPUTexture *colorramp_texture; | |||||
| } PAINT_WEIGHT_TextureList; | |||||
| typedef struct PAINT_WEIGHT_StorageList { | typedef struct PAINT_WEIGHT_StorageList { | ||||
| struct PAINT_WEIGHT_PrivateData *g_data; | struct PAINT_WEIGHT_PrivateData *g_data; | ||||
| } PAINT_WEIGHT_StorageList; | } PAINT_WEIGHT_StorageList; | ||||
| typedef struct PAINT_WEIGHT_Data { | typedef struct PAINT_WEIGHT_Data { | ||||
| void *engine_type; | void *engine_type; | ||||
| DRWViewportEmptyList *fbl; | DRWViewportEmptyList *fbl; | ||||
| DRWViewportEmptyList *txl; | PAINT_WEIGHT_TextureList *txl; | ||||
| PAINT_WEIGHT_PassList *psl; | PAINT_WEIGHT_PassList *psl; | ||||
| PAINT_WEIGHT_StorageList *stl; | PAINT_WEIGHT_StorageList *stl; | ||||
| } PAINT_WEIGHT_Data; | } PAINT_WEIGHT_Data; | ||||
| /* *********** STATIC *********** */ | /* *********** STATIC *********** */ | ||||
| static struct { | static struct { | ||||
| struct GPUShader *weight_face_shader; | struct GPUShader *weight_face_shader; | ||||
| struct GPUShader *wire_overlay_shader; | struct GPUShader *wire_overlay_shader; | ||||
| struct GPUShader *face_overlay_shader; | struct GPUShader *face_overlay_shader; | ||||
| struct GPUShader *vert_overlay_shader; | struct GPUShader *vert_overlay_shader; | ||||
| int actdef; | int actdef; | ||||
| } e_data = {NULL}; /* Engine data */ | } e_data = {NULL}; /* Engine data */ | ||||
| typedef struct PAINT_WEIGHT_PrivateData { | typedef struct PAINT_WEIGHT_PrivateData { | ||||
| DRWShadingGroup *fweights_shgrp; | DRWShadingGroup *fweights_shgrp; | ||||
| DRWShadingGroup *lwire_shgrp; | DRWShadingGroup *lwire_shgrp; | ||||
| DRWShadingGroup *face_shgrp; | DRWShadingGroup *face_shgrp; | ||||
| DRWShadingGroup *vert_shgrp; | DRWShadingGroup *vert_shgrp; | ||||
| int colorramp_flag; | |||||
| ColorBand colorramp_copy; | |||||
| } PAINT_WEIGHT_PrivateData; | } PAINT_WEIGHT_PrivateData; | ||||
| /* Private functions */ | |||||
| static void paint_weight_ensure_colorramp_texture(PAINT_WEIGHT_Data *vedata) | |||||
fclem: no need for uper case prefix if function is static | |||||
| { | |||||
| PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl; | |||||
| PAINT_WEIGHT_PrivateData *pd = stl->g_data; | |||||
| PAINT_WEIGHT_TextureList *txl = ((PAINT_WEIGHT_Data *)vedata)->txl; | |||||
| if ((U.flag & USER_CUSTOM_RANGE) != pd->colorramp_flag) { | |||||
| DRW_TEXTURE_FREE_SAFE(txl->colorramp_texture); | |||||
Done Inline ActionsBracket style fclem: Bracket style | |||||
| pd->colorramp_flag = U.flag & USER_CUSTOM_RANGE; | |||||
| } | |||||
| else if (U.flag & USER_CUSTOM_RANGE) { | |||||
| if (memcmp(&pd->colorramp_copy, &U.coba_weight, sizeof(ColorBand)) != 0) | |||||
| { | |||||
| DRW_TEXTURE_FREE_SAFE(txl->colorramp_texture); | |||||
| } | |||||
| } | |||||
| if (txl->colorramp_texture == NULL) { | |||||
| txl->colorramp_texture = DRW_create_colorramp_texture(); | |||||
| } | |||||
| if (U.flag & USER_CUSTOM_RANGE) { | |||||
Done Inline ActionsI'm not sure about putting it here. I would prefer to have a ramp texture common to all viewports. There is already a globals_ramp in draw_common.c. fclem: I'm not sure about putting it here. I would prefer to have a ramp texture common to all… | |||||
| memcpy(&pd->colorramp_copy, &U.coba_weight, sizeof(ColorBand)); | |||||
| } | |||||
| } | |||||
| /* *********** FUNCTIONS *********** */ | /* *********** FUNCTIONS *********** */ | ||||
| static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata)) | static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata)) | ||||
| { | { | ||||
| if (!e_data.weight_face_shader) { | if (!e_data.weight_face_shader) { | ||||
| e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_MULTIPLY_AND_BLEND_PREPROCESSING); | e_data.weight_face_shader = DRW_shader_create(datatoc_paint_weight_vert_glsl, NULL, datatoc_paint_weight_frag_glsl, NULL); | ||||
| } | } | ||||
| if (!e_data.wire_overlay_shader) { | if (!e_data.wire_overlay_shader) { | ||||
| e_data.wire_overlay_shader = DRW_shader_create_with_lib( | e_data.wire_overlay_shader = DRW_shader_create_with_lib( | ||||
| datatoc_paint_wire_vert_glsl, NULL, | datatoc_paint_wire_vert_glsl, NULL, | ||||
| datatoc_paint_wire_frag_glsl, | datatoc_paint_wire_frag_glsl, | ||||
| datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n"); | datatoc_common_globals_lib_glsl, "#define WEIGHT_MODE\n"); | ||||
| } | } | ||||
| if (!e_data.face_overlay_shader) { | if (!e_data.face_overlay_shader) { | ||||
| e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); | e_data.face_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); | ||||
| } | } | ||||
| if (!e_data.vert_overlay_shader) { | if (!e_data.vert_overlay_shader) { | ||||
| e_data.vert_overlay_shader = DRW_shader_create_with_lib( | e_data.vert_overlay_shader = DRW_shader_create_with_lib( | ||||
| datatoc_paint_wire_vert_glsl, NULL, | datatoc_paint_wire_vert_glsl, NULL, | ||||
| datatoc_paint_vert_frag_glsl, | datatoc_paint_vert_frag_glsl, | ||||
| datatoc_common_globals_lib_glsl, NULL); | datatoc_common_globals_lib_glsl, NULL); | ||||
| } | } | ||||
| } | } | ||||
| /* color-code for missing data (full brightness isn't easy on the eye). */ | |||||
| static const unsigned char missing_weight_color[3] = { 0xa0, 0x00, 0xa0 }; | |||||
| static void PAINT_WEIGHT_cache_init(void *vedata) | static void PAINT_WEIGHT_cache_init(void *vedata) | ||||
| { | { | ||||
| PAINT_WEIGHT_TextureList *txl = ((PAINT_WEIGHT_Data *)vedata)->txl; | |||||
| PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl; | PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl; | ||||
| PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl; | PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| const View3D *v3d = draw_ctx->v3d; | const View3D *v3d = draw_ctx->v3d; | ||||
| 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__); | ||||
| } | } | ||||
| { | { | ||||
| paint_weight_ensure_colorramp_texture(vedata); | |||||
| } | |||||
| { | |||||
| /* Create a pass */ | /* Create a pass */ | ||||
| psl->weight_faces = DRW_pass_create( | psl->weight_faces = DRW_pass_create( | ||||
| "Weight Pass", | "Weight Pass", | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY); | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_MULTIPLY); | ||||
| stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces); | stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces); | ||||
| bTheme *theme = U.themes.first; | |||||
| static float alert_colors[2][3]; | |||||
angavrilovAuthorUnsubmitted Done Inline ActionsThere is very likely a better place to put this color buffer and its initialization code, but I don't know where it is. angavrilov: There is very likely a better place to put this color buffer and its initialization code, but I… | |||||
| rgb_uchar_to_float(alert_colors[0], (unsigned char*)theme->tv3d.vertex_unreferenced); | |||||
| rgb_uchar_to_float(alert_colors[1], missing_weight_color); | |||||
| DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1); | DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "opacity", &v3d->overlay.weight_paint_mode_opacity, 1); | ||||
| DRW_shgroup_uniform_texture(stl->g_data->fweights_shgrp, "colorramp", txl->colorramp_texture); | |||||
| DRW_shgroup_uniform_vec3(stl->g_data->fweights_shgrp, "alert_colors[0]", &alert_colors[0][0], 2); | |||||
| } | } | ||||
| { | { | ||||
| psl->wire_overlay = DRW_pass_create( | psl->wire_overlay = DRW_pass_create( | ||||
| "Wire Pass", | "Wire Pass", | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); | ||||
| stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); | stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | static void PAINT_WEIGHT_draw_scene(void *vedata) | ||||
| DRW_draw_pass(psl->weight_faces); | DRW_draw_pass(psl->weight_faces); | ||||
| DRW_draw_pass(psl->face_overlay); | DRW_draw_pass(psl->face_overlay); | ||||
| DRW_draw_pass(psl->wire_overlay); | DRW_draw_pass(psl->wire_overlay); | ||||
| DRW_draw_pass(psl->vert_overlay); | DRW_draw_pass(psl->vert_overlay); | ||||
| } | } | ||||
| static void PAINT_WEIGHT_engine_free(void) | static void PAINT_WEIGHT_engine_free(void) | ||||
| { | { | ||||
| DRW_SHADER_FREE_SAFE(e_data.weight_face_shader); | |||||
| DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); | DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); | ||||
| DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader); | DRW_SHADER_FREE_SAFE(e_data.vert_overlay_shader); | ||||
| } | } | ||||
| static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data); | static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data); | ||||
| DrawEngineType draw_engine_paint_weight_type = { | DrawEngineType draw_engine_paint_weight_type = { | ||||
| NULL, NULL, | NULL, NULL, | ||||
| Show All 12 Lines | |||||
no need for uper case prefix if function is static