Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/gpencil/gpencil_engine.c
| Context not available. | |||||
| } | } | ||||
| if (txl->multisample_depth == NULL) { | if (txl->multisample_depth == NULL) { | ||||
| txl->multisample_depth = GPU_texture_create_2d_multisample( | txl->multisample_depth = GPU_texture_create_2d_multisample( | ||||
| rect_w, rect_h, GPU_DEPTH_COMPONENT24, NULL, samples, NULL); | rect_w, rect_h, GPU_DEPTH24_STENCIL8, NULL, samples, NULL); | ||||
| } | } | ||||
| GPU_framebuffer_ensure_config(&fbl->multisample_fb, | GPU_framebuffer_ensure_config(&fbl->multisample_fb, | ||||
| {GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), | {GPU_ATTACHMENT_TEXTURE(txl->multisample_depth), | ||||
| Context not available. | |||||
| if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) { | if (stl->storage->framebuffer_flag & GP_FRAMEBUFFER_BASIC) { | ||||
| /* temp textures for ping-pong buffers */ | /* temp textures for ping-pong buffers */ | ||||
| stl->g_data->temp_depth_tx_a = DRW_texture_pool_query_2d( | stl->g_data->temp_depth_tx_a = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type); | size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type); | ||||
| stl->g_data->temp_color_tx_a = DRW_texture_pool_query_2d( | stl->g_data->temp_color_tx_a = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], fb_format, &draw_engine_gpencil_type); | size[0], size[1], fb_format, &draw_engine_gpencil_type); | ||||
| GPU_framebuffer_ensure_config(&fbl->temp_fb_a, | GPU_framebuffer_ensure_config(&fbl->temp_fb_a, | ||||
| Context not available. | |||||
| }); | }); | ||||
| stl->g_data->temp_depth_tx_b = DRW_texture_pool_query_2d( | stl->g_data->temp_depth_tx_b = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type); | size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type); | ||||
| stl->g_data->temp_color_tx_b = DRW_texture_pool_query_2d( | stl->g_data->temp_color_tx_b = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], fb_format, &draw_engine_gpencil_type); | size[0], size[1], fb_format, &draw_engine_gpencil_type); | ||||
| GPU_framebuffer_ensure_config(&fbl->temp_fb_b, | GPU_framebuffer_ensure_config(&fbl->temp_fb_b, | ||||
| Context not available. | |||||
| /* used for FX effects and Layer blending */ | /* used for FX effects and Layer blending */ | ||||
| stl->g_data->temp_depth_tx_fx = DRW_texture_pool_query_2d( | stl->g_data->temp_depth_tx_fx = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type); | size[0], size[1], GPU_DEPTH24_STENCIL8, &draw_engine_gpencil_type); | ||||
| stl->g_data->temp_color_tx_fx = DRW_texture_pool_query_2d( | stl->g_data->temp_color_tx_fx = DRW_texture_pool_query_2d( | ||||
| size[0], size[1], fb_format, &draw_engine_gpencil_type); | size[0], size[1], fb_format, &draw_engine_gpencil_type); | ||||
| GPU_framebuffer_ensure_config(&fbl->temp_fb_fx, | GPU_framebuffer_ensure_config(&fbl->temp_fb_fx, | ||||
| Context not available. | |||||
| /* Stroke pass 2D */ | /* Stroke pass 2D */ | ||||
| psl->stroke_pass_2d = DRW_pass_create("GPencil Stroke Pass", | psl->stroke_pass_2d = DRW_pass_create("GPencil Stroke Pass", | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | | ||||
| DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA); | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA | | ||||
| DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); | |||||
| stl->storage->shgroup_id = 0; | stl->storage->shgroup_id = 0; | ||||
| /* Stroke pass 3D */ | /* Stroke pass 3D */ | ||||
| psl->stroke_pass_3d = DRW_pass_create("GPencil Stroke Pass", | psl->stroke_pass_3d = DRW_pass_create("GPencil Stroke Pass", | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | | ||||
| DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA); | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA | | ||||
| DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); | |||||
| stl->storage->shgroup_id = 0; | stl->storage->shgroup_id = 0; | ||||
| /* edit pass */ | /* edit pass */ | ||||
| Context not available. | |||||
| */ | */ | ||||
| psl->drawing_pass = DRW_pass_create("GPencil Drawing Pass", | psl->drawing_pass = DRW_pass_create("GPencil Drawing Pass", | ||||
| DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | | DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA | | ||||
| DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS); | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | | ||||
| DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_NEQUAL); | |||||
| /* full screen pass to combine the result with default framebuffer */ | /* full screen pass to combine the result with default framebuffer */ | ||||
| struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); | struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); | ||||
| Context not available. | |||||
| GPU_framebuffer_bind(fbl->background_fb); | GPU_framebuffer_bind(fbl->background_fb); | ||||
| /* clean only in first loop cycle */ | /* clean only in first loop cycle */ | ||||
| if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) { | if (stl->g_data->session_flag & GP_DRW_PAINT_IDLE) { | ||||
| GPU_framebuffer_clear_color_depth(fbl->background_fb, clearcol, 1.0f); | GPU_framebuffer_clear_color_depth_stencil(fbl->background_fb, clearcol, 1.0f, 0x0); | ||||
| stl->g_data->session_flag = GP_DRW_PAINT_FILLING; | stl->g_data->session_flag = GP_DRW_PAINT_FILLING; | ||||
| } | } | ||||
| /* repeat pass to fill temp texture */ | /* repeat pass to fill temp texture */ | ||||
| Context not available. | |||||
| return; | return; | ||||
| } | } | ||||
| /* previews don't use AA */ | const bool do_antialiasing = ((!stl->storage->is_mat_preview) && (multi)); | ||||
| if ((!stl->storage->is_mat_preview) && (multi)) { | |||||
| DRWShadingGroup *shgrp = init_shgrp; | |||||
| DRWShadingGroup *from_shgrp = init_shgrp; | |||||
| DRWShadingGroup *to_shgrp = init_shgrp; | |||||
| int stencil_tot = 0; | |||||
| bool do_last = true; | |||||
| if (do_antialiasing) { | |||||
| MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl); | MULTISAMPLE_GP_SYNC_ENABLE(stl->storage->multisamples, fbl); | ||||
| } | } | ||||
| DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d, | /* Loop all shading groups to separate by stencil groups. */ | ||||
| init_shgrp, | while ((shgrp) && (shgrp != end_shgrp)) { | ||||
| end_shgrp); | do_last = true; | ||||
| /* Count number of groups using stencil. */ | |||||
| if (DRW_shgroup_stencil_mask_get(shgrp) != 0) { | |||||
| stencil_tot++; | |||||
| } | |||||
| /* Draw stencil group and clear stencil bit. This is required because the number of | |||||
| * shading groups can be greater than the limit of 255 stencil values. | |||||
| * Only count as stencil if the shading group has an stencil value assigned. This reduces | |||||
| * the number of clears because Dots, Fills and some Line strokes don't need stencil. | |||||
| */ | |||||
| if (stencil_tot == 255) { | |||||
| DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : | |||||
| psl->stroke_pass_2d, | |||||
| from_shgrp, | |||||
| to_shgrp); | |||||
| /* Clear Stencil and prepare for next group. */ | |||||
| if (do_antialiasing) { | |||||
| GPU_framebuffer_clear_stencil(fbl->multisample_fb, 0x0); | |||||
| } | |||||
| else { | |||||
| GPU_framebuffer_clear_stencil(fb, 0x0); | |||||
| } | |||||
| /* Set new init group and reset. */ | |||||
| do_last = false; | |||||
| shgrp = DRW_shgroup_get_next(shgrp); | |||||
| if (shgrp) { | |||||
| from_shgrp = to_shgrp = shgrp; | |||||
| stencil_tot = 0; | |||||
| if (shgrp != end_shgrp) { | |||||
| continue; | |||||
| } | |||||
| else { | |||||
| do_last = true; | |||||
| break; | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* No more groups. */ | |||||
| break; | |||||
| } | |||||
| } | |||||
| /* Still below stencil group limit. */ | |||||
| shgrp = DRW_shgroup_get_next(shgrp); | |||||
| if (shgrp) { | |||||
| to_shgrp = shgrp; | |||||
| } | |||||
| } | |||||
| /* Draw last pending groups. */ | |||||
| if (do_last) { | |||||
| DRW_draw_pass_subset(GPENCIL_3D_DRAWMODE(ob, gpd) ? psl->stroke_pass_3d : psl->stroke_pass_2d, | |||||
| from_shgrp, | |||||
| to_shgrp); | |||||
| } | |||||
| if ((!stl->storage->is_mat_preview) && (multi)) { | if (do_antialiasing) { | ||||
| MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl); | MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, fb, txl); | ||||
| } | } | ||||
| } | } | ||||
| Context not available. | |||||
| init_shgrp = NULL; | init_shgrp = NULL; | ||||
| /* Render stroke in separated framebuffer */ | /* Render stroke in separated framebuffer */ | ||||
| GPU_framebuffer_bind(fbl->temp_fb_a); | GPU_framebuffer_bind(fbl->temp_fb_a); | ||||
| GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); | GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_a, clearcol, 1.0f, 0x0); | ||||
| /* Stroke Pass: | /* Stroke Pass: | ||||
| * draw only a subset that usually starts with a fill and ends with stroke | * draw only a subset that usually starts with a fill and ends with stroke | ||||
| */ | */ | ||||
| Context not available. | |||||
| end_shgrp = array_elm->end_shgrp; | end_shgrp = array_elm->end_shgrp; | ||||
| GPU_framebuffer_bind(fbl->temp_fb_fx); | GPU_framebuffer_bind(fbl->temp_fb_fx); | ||||
| GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f); | GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_fx, clearcol, 1.0f, 0x0); | ||||
| gpencil_draw_pass_range( | gpencil_draw_pass_range( | ||||
| fbl, stl, psl, txl, fbl->temp_fb_fx, ob, gpd, init_shgrp, end_shgrp, is_last); | fbl, stl, psl, txl, fbl->temp_fb_fx, ob, gpd, init_shgrp, end_shgrp, is_last); | ||||
| /* Blend A texture and FX texture */ | /* Blend A texture and FX texture */ | ||||
| GPU_framebuffer_bind(fbl->temp_fb_b); | GPU_framebuffer_bind(fbl->temp_fb_b); | ||||
| GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f); | GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_b, clearcol, 1.0f, 0x0); | ||||
| stl->storage->blend_mode = array_elm->mode; | stl->storage->blend_mode = array_elm->mode; | ||||
| stl->storage->clamp_layer = (int)array_elm->clamp_layer; | stl->storage->clamp_layer = (int)array_elm->clamp_layer; | ||||
| stl->storage->tonemapping = DRW_state_do_color_management() ? 0 : 1; | stl->storage->tonemapping = DRW_state_do_color_management() ? 0 : 1; | ||||
| Context not available. | |||||
| stl->g_data->input_color_tx = stl->g_data->temp_color_tx_b; | stl->g_data->input_color_tx = stl->g_data->temp_color_tx_b; | ||||
| GPU_framebuffer_bind(fbl->temp_fb_a); | GPU_framebuffer_bind(fbl->temp_fb_a); | ||||
| GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f); | GPU_framebuffer_clear_color_depth_stencil(fbl->temp_fb_a, clearcol, 1.0f, 0x0); | ||||
| DRW_draw_pass(psl->mix_pass_noblend); | DRW_draw_pass(psl->mix_pass_noblend); | ||||
| /* prepare next group */ | /* prepare next group */ | ||||
| Context not available. | |||||