Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/modes/paint_texture_mode.c
| Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | |||||
| static struct { | static struct { | ||||
| /* Custom shaders : | /* Custom shaders : | ||||
| * Add sources to source/blender/draw/modes/shaders | * Add sources to source/blender/draw/modes/shaders | ||||
| * init in PAINT_TEXTURE_engine_init(); | * init in PAINT_TEXTURE_engine_init(); | ||||
| * free in PAINT_TEXTURE_engine_free(); */ | * free in PAINT_TEXTURE_engine_free(); */ | ||||
| struct GPUShader *fallback_sh; | struct GPUShader *fallback_sh; | ||||
| struct GPUShader *image_sh; | struct GPUShader *image_sh; | ||||
| struct GPUShader *image_masking_sh; | |||||
| struct GPUShader *wire_overlay_shader; | struct GPUShader *wire_overlay_shader; | ||||
| struct GPUShader *face_overlay_shader; | struct GPUShader *face_overlay_shader; | ||||
| } e_data = {NULL}; /* Engine data */ | } e_data = {NULL}; /* Engine data */ | ||||
| typedef struct PAINT_TEXTURE_PrivateData { | typedef struct PAINT_TEXTURE_PrivateData { | ||||
| /* This keeps the references of the shading groups for | /* This keeps the references of the shading groups for | ||||
| * easy access in PAINT_TEXTURE_cache_populate() */ | * easy access in PAINT_TEXTURE_cache_populate() */ | ||||
| Show All 14 Lines | static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata)) | ||||
| if (!e_data.fallback_sh) { | if (!e_data.fallback_sh) { | ||||
| e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); | e_data.fallback_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); | ||||
| e_data.image_sh = DRW_shader_create_with_lib( | e_data.image_sh = DRW_shader_create_with_lib( | ||||
| datatoc_paint_texture_vert_glsl, NULL, | datatoc_paint_texture_vert_glsl, NULL, | ||||
| datatoc_paint_texture_frag_glsl, | datatoc_paint_texture_frag_glsl, | ||||
| datatoc_common_globals_lib_glsl, NULL); | datatoc_common_globals_lib_glsl, NULL); | ||||
| e_data.image_masking_sh = DRW_shader_create_with_lib( | |||||
| datatoc_paint_texture_vert_glsl, NULL, | |||||
| datatoc_paint_texture_frag_glsl, | |||||
| datatoc_common_globals_lib_glsl, | |||||
| "#define TEXTURE_PAINT_MASK\n"); | |||||
| 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, | datatoc_common_globals_lib_glsl, | ||||
| "#define VERTEX_MODE\n"); | "#define VERTEX_MODE\n"); | ||||
| e_data.face_overlay_shader = DRW_shader_create( | e_data.face_overlay_shader = DRW_shader_create( | ||||
| datatoc_paint_face_vert_glsl, NULL, | datatoc_paint_face_vert_glsl, NULL, | ||||
| datatoc_gpu_shader_uniform_color_frag_glsl, NULL); | datatoc_gpu_shader_uniform_color_frag_glsl, NULL); | ||||
| } | } | ||||
| } | } | ||||
| static DRWShadingGroup* create_texture_paint_shading_group(PAINT_TEXTURE_PassList *psl, const struct GPUTexture *texture, const DRWContextState *draw_ctx, const bool nearest_interp) | |||||
| { | |||||
| Scene *scene = draw_ctx->scene; | |||||
| const ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; | |||||
| const bool masking_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL && imapaint->stencil != NULL; | |||||
| DRWShadingGroup *grp = DRW_shgroup_create(masking_enabled?e_data.image_masking_sh:e_data.image_sh, psl->image_faces); | |||||
| DRW_shgroup_uniform_texture(grp, "image", texture); | |||||
| DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1); | |||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", nearest_interp); | |||||
| if (masking_enabled) { | |||||
| const bool masking_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) > 0; | |||||
| GPUTexture *stencil = GPU_texture_from_blender(imapaint->stencil, NULL, GL_TEXTURE_2D, false); | |||||
| DRW_shgroup_uniform_texture(grp, "maskingImage", stencil); | |||||
| DRW_shgroup_uniform_vec3(grp, "maskingColor", imapaint->stencil_col, 1); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "maskingInvertStencil", masking_inverted); | |||||
| } | |||||
| return grp; | |||||
| } | |||||
| /* 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 PAINT_TEXTURE_cache_init(void *vedata) | static void PAINT_TEXTURE_cache_init(void *vedata) | ||||
| { | { | ||||
| PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl; | PAINT_TEXTURE_PassList *psl = ((PAINT_TEXTURE_Data *)vedata)->psl; | ||||
| PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl; | PAINT_TEXTURE_StorageList *stl = ((PAINT_TEXTURE_Data *)vedata)->stl; | ||||
| if (!stl->g_data) { | if (!stl->g_data) { | ||||
| Show All 28 Lines | if (ob && ob->type == OB_MESH) { | ||||
| stl->g_data->shgroup_image_array = MEM_mallocN( | stl->g_data->shgroup_image_array = MEM_mallocN( | ||||
| sizeof(*stl->g_data->shgroup_image_array) * (use_material_slots ? mat_nr : 1), __func__); | sizeof(*stl->g_data->shgroup_image_array) * (use_material_slots ? mat_nr : 1), __func__); | ||||
| if (use_material_slots) { | if (use_material_slots) { | ||||
| for (int i = 0; i < mat_nr; i++) { | for (int i = 0; i < mat_nr; i++) { | ||||
| Material *ma = give_current_material(ob, i + 1); | Material *ma = give_current_material(ob, i + 1); | ||||
| Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; | Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; | ||||
| int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp : 0; | int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp : 0; | ||||
| GPUTexture *tex = ima ? | GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false); | ||||
| GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL; | |||||
| if (tex) { | if (tex) { | ||||
| DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); | DRWShadingGroup *grp = create_texture_paint_shading_group(psl, tex, draw_ctx, interp == SHD_INTERP_CLOSEST); | ||||
| DRW_shgroup_uniform_texture(grp, "image", tex); | |||||
| DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1); | |||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", interp == SHD_INTERP_CLOSEST); | |||||
| stl->g_data->shgroup_image_array[i] = grp; | stl->g_data->shgroup_image_array[i] = grp; | ||||
| } | } | ||||
| else { | else { | ||||
| stl->g_data->shgroup_image_array[i] = NULL; | stl->g_data->shgroup_image_array[i] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| Image *ima = imapaint->canvas; | Image *ima = imapaint->canvas; | ||||
| GPUTexture *tex = ima ? | GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false); | ||||
| GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL; | |||||
| if (tex) { | if (tex) { | ||||
| DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); | DRWShadingGroup *grp = create_texture_paint_shading_group(psl, tex, draw_ctx, imapaint->interp == IMAGEPAINT_INTERP_CLOSEST); | ||||
| DRW_shgroup_uniform_texture(grp, "image", tex); | |||||
| DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1); | |||||
| DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); | |||||
| DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", imapaint->interp == IMAGEPAINT_INTERP_CLOSEST); | |||||
| stl->g_data->shgroup_image_array[0] = grp; | stl->g_data->shgroup_image_array[0] = grp; | ||||
| } | } | ||||
| else { | else { | ||||
| stl->g_data->shgroup_image_array[0] = NULL; | stl->g_data->shgroup_image_array[0] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* 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. | ||||
| * Mostly used for freeing shaders */ | * Mostly used for freeing shaders */ | ||||
| static void PAINT_TEXTURE_engine_free(void) | static void PAINT_TEXTURE_engine_free(void) | ||||
| { | { | ||||
| DRW_SHADER_FREE_SAFE(e_data.image_sh); | DRW_SHADER_FREE_SAFE(e_data.image_sh); | ||||
| DRW_SHADER_FREE_SAFE(e_data.image_masking_sh); | |||||
| DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); | DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader); | ||||
| DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader); | DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader); | ||||
| } | } | ||||
| static const DrawEngineDataSize PAINT_TEXTURE_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_TEXTURE_Data); | static const DrawEngineDataSize PAINT_TEXTURE_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_TEXTURE_Data); | ||||
| DrawEngineType draw_engine_paint_texture_type = { | DrawEngineType draw_engine_paint_texture_type = { | ||||
| NULL, NULL, | NULL, NULL, | ||||
| Show All 12 Lines | |||||