GPencil: Remove legacy `ED_gpencil_draw_view3d` code.

Differential Revision: https://developer.blender.org/D4598
This commit is contained in:
Germano Cavalcante 2019-03-27 10:52:13 -03:00
parent c87e467e39
commit 27b73f0c5b
7 changed files with 119 additions and 676 deletions

View File

@ -123,6 +123,10 @@ void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
struct ARegion *ar, struct View3D *v3d,
struct GPUViewport *viewport);
void DRW_draw_depth_loop_gpencil(
struct Depsgraph *depsgraph,
struct ARegion *ar, struct View3D *v3d,
struct GPUViewport *viewport);
void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
void DRW_framebuffer_select_id_release(struct ARegion *ar);

View File

@ -414,7 +414,8 @@ void GPENCIL_cache_init(void *vedata)
bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id);
if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) &&
(gpd_orig->runtime.sbuffer_size > 0) &&
((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0))
((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0) &&
!DRW_state_is_depth())
{
stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING;
}
@ -710,7 +711,7 @@ void GPENCIL_cache_finish(void *vedata)
}
/* create framebuffers (only for normal drawing) */
if (!DRW_state_is_select()) {
if (!DRW_state_is_select() || !DRW_state_is_depth()) {
GPENCIL_create_framebuffers(vedata);
}
}
@ -864,7 +865,7 @@ void GPENCIL_draw_scene(void *ved)
const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true;
/* if the draw is for select, do a basic drawing and return */
if (DRW_state_is_select()) {
if (DRW_state_is_select() || DRW_state_is_depth()) {
drw_gpencil_select_render(stl, psl);
/* free memory */
gpencil_free_obj_runtime(stl);

View File

@ -2329,48 +2329,19 @@ static void draw_depth_texture_to_screen(GPUTexture *texture)
immUnbindProgram();
}
/**
* object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
*/
void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
ARegion *ar, View3D *v3d,
GPUViewport *viewport)
static void drw_draw_depth_loop_imp(void)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
DRW_opengl_context_enable();
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
DST.viewport = viewport;
DST.options.is_depth = true;
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
.ar = ar, .rv3d = rv3d, .v3d = v3d,
.scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
.engine_type = engine_type,
.depsgraph = depsgraph,
};
/* Setup framebuffer */
DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(viewport);
DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport);
GPU_framebuffer_bind(fbl->depth_only_fb);
GPU_framebuffer_clear_depth(fbl->depth_only_fb, 1.0f);
/* Get list of enabled engines */
{
drw_engines_enable_basic();
if (DRW_state_draw_support()) {
drw_engines_enable_from_object_mode();
}
}
/* Setup viewport */
drw_context_state_init();
drw_viewport_var_init();
@ -2384,10 +2355,11 @@ void DRW_draw_depth_loop(
{
drw_engines_cache_init();
drw_engines_world_update(scene);
drw_engines_world_update(DST.draw_ctx.scene);
View3D *v3d = DST.draw_ctx.v3d;
const int object_type_exclude_viewport = v3d->object_type_exclude_viewport;
DEG_OBJECT_ITER_BEGIN(depsgraph, ob,
DEG_OBJECT_ITER_BEGIN(DST.draw_ctx.depsgraph, ob,
DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE |
@ -2422,12 +2394,6 @@ void DRW_draw_depth_loop(
DRW_draw_callbacks_post_scene();
DRW_state_reset();
drw_engines_disable();
#ifdef DEBUG
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
/* TODO: Reading depth for operators should be done here. */
@ -2435,16 +2401,56 @@ void DRW_draw_depth_loop(
/* Changin context */
DRW_opengl_context_disable();
}
/**
* object mode select-loop, see: ED_view3d_draw_depth_loop (legacy drawing).
*/
void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
ARegion *ar, View3D *v3d,
GPUViewport *viewport)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
DST.viewport = viewport;
DST.options.is_depth = true;
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
.ar = ar, .rv3d = rv3d, .v3d = v3d,
.scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
.engine_type = engine_type,
.depsgraph = depsgraph,
};
/* Get list of enabled engines */
{
drw_engines_enable_basic();
if (DRW_state_draw_support()) {
drw_engines_enable_from_object_mode();
}
}
drw_draw_depth_loop_imp();
drw_engines_disable();
/* XXX Drawing the resulting buffer to the BACK_BUFFER */
GPU_matrix_push();
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
wmOrtho2_region_pixelspace(DST.draw_ctx.ar);
GPU_matrix_identity_set();
glEnable(GL_DEPTH_TEST); /* Cannot write to depth buffer without testing */
glDepthFunc(GL_ALWAYS);
DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport);
DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(DST.viewport);
draw_depth_texture_to_screen(dtxl->depth);
glDepthFunc(GL_LEQUAL);
@ -2452,6 +2458,41 @@ void DRW_draw_depth_loop(
GPU_matrix_pop_projection();
}
/**
* Converted from ED_view3d_draw_depth_gpencil (legacy drawing).
*/
void DRW_draw_depth_loop_gpencil(
struct Depsgraph *depsgraph,
ARegion *ar, View3D *v3d,
GPUViewport *viewport)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
RegionView3D *rv3d = ar->regiondata;
/* Reset before using it. */
drw_state_prepare_clean_for_draw(&DST);
DST.viewport = viewport;
DST.options.is_depth = true;
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
.ar = ar, .rv3d = rv3d, .v3d = v3d,
.scene = scene, .view_layer = view_layer, .obact = OBACT(view_layer),
.depsgraph = depsgraph,
};
use_drw_engine(&draw_engine_gpencil_type);
drw_draw_depth_loop_imp();
drw_engines_disable();
#ifdef DEBUG
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
}
/* Set an opengl context to be used with shaders that draw on U32 colors. */
void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
@ -2496,6 +2537,11 @@ void DRW_framebuffer_select_id_release(ARegion *ar)
glEnable(GL_DITHER);
DRW_opengl_context_disable();
#ifdef DEBUG
/* Avoid accidental reuse. */
drw_state_ensure_not_reused(&DST);
#endif
}

View File

@ -117,13 +117,6 @@ typedef enum eDrawStrokeFlags {
/* ----- Tool Buffer Drawing ------ */
/* helper functions to set color of buffer point */
static void gp_set_tpoint_varying_color(const tGPspoint *pt, const float ink[4], uint attr_id)
{
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
immAttr4ub(attr_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
}
static void gp_set_point_uniform_color(const bGPDspoint *pt, const float ink[4])
{
float alpha = ink[3] * pt->strength;
@ -138,161 +131,6 @@ static void gp_set_point_varying_color(const bGPDspoint *pt, const float ink[4],
immAttr4ub(attr_id, F2UB(ink[0]), F2UB(ink[1]), F2UB(ink[2]), F2UB(alpha));
}
/* draw fills for buffer stroke */
static void gp_draw_stroke_buffer_fill(const tGPspoint *points, int totpoints, float ink[4])
{
if (totpoints < 3) {
return;
}
int tot_triangles = totpoints - 2;
/* allocate memory for temporary areas */
uint(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * tot_triangles, "GP Stroke buffer temp triangulation");
float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * totpoints, "GP Stroke buffer temp 2d points");
/* Convert points to array and triangulate
* Here a cache is not used because while drawing the information changes all the time, so the cache
* would be recalculated constantly, so it is better to do direct calculation for each function call
*/
for (int i = 0; i < totpoints; i++) {
const tGPspoint *pt = &points[i];
points2d[i][0] = pt->x;
points2d[i][1] = pt->y;
}
BLI_polyfill_calc((const float(*)[2])points2d, (uint)totpoints, 0, (uint(*)[3])tmp_triangles);
/* draw triangulation data */
if (tot_triangles > 0) {
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* Draw all triangles for filling the polygon */
immBegin(GPU_PRIM_TRIS, tot_triangles * 3);
/* TODO: use batch instead of immediate mode, to share vertices */
const tGPspoint *pt;
for (int i = 0; i < tot_triangles; i++) {
/* vertex 1 */
pt = &points[tmp_triangles[i][0]];
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2fv(pos, &pt->x);
/* vertex 2 */
pt = &points[tmp_triangles[i][1]];
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2fv(pos, &pt->x);
/* vertex 3 */
pt = &points[tmp_triangles[i][2]];
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2fv(pos, &pt->x);
}
immEnd();
immUnbindProgram();
}
/* clear memory */
if (tmp_triangles) {
MEM_freeN(tmp_triangles);
}
if (points2d) {
MEM_freeN(points2d);
}
}
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
static void gp_draw_stroke_buffer(
const tGPspoint *points, int totpoints, short thickness,
short dflag, short sflag, float ink[4], float fill_ink[4])
{
int draw_points = 0;
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
/* check if buffer can be drawn */
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
return;
if (sflag & GP_STROKE_ERASER) {
/* don't draw stroke at all! */
return;
}
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
const tGPspoint *pt = points;
if (totpoints == 1) {
/* if drawing a single point, draw it larger */
GPU_point_size((float)(thickness + 2) * points->pressure);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
immBegin(GPU_PRIM_POINTS, 1);
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2fv(pos, &pt->x);
}
else {
float oldpressure = points[0].pressure;
/* draw stroke curve */
GPU_line_width(max_ff(oldpressure * thickness, 1.0));
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints);
/* TODO: implement this with a geometry shader to draw one continuous tapered stroke */
for (int i = 0; i < totpoints; i++, pt++) {
/* if there was a significant pressure change, stop the curve, change the thickness of the stroke,
* and continue drawing again (since line-width cannot change in middle of GL_LINE_STRIP)
*/
if (fabsf(pt->pressure - oldpressure) > 0.2f) {
/* need to have 2 points to avoid immEnd assert error */
if (draw_points < 2) {
gp_set_tpoint_varying_color(pt - 1, ink, color);
immVertex2fv(pos, &(pt - 1)->x);
}
immEnd();
draw_points = 0;
GPU_line_width(max_ff(pt->pressure * thickness, 1.0f));
immBeginAtMost(GPU_PRIM_LINE_STRIP, totpoints - i + 1);
/* need to roll-back one point to ensure that there are no gaps in the stroke */
if (i != 0) {
gp_set_tpoint_varying_color(pt - 1, ink, color);
immVertex2fv(pos, &(pt - 1)->x);
draw_points++;
}
oldpressure = pt->pressure; /* reset our threshold */
}
/* now the point we want */
gp_set_tpoint_varying_color(pt, ink, color);
immVertex2fv(pos, &pt->x);
draw_points++;
}
/* need to have 2 points to avoid immEnd assert error */
if (draw_points < 2) {
gp_set_tpoint_varying_color(pt - 1, ink, color);
immVertex2fv(pos, &(pt - 1)->x);
}
}
immEnd();
immUnbindProgram();
// draw fill
if (fill_ink[3] > GPENCIL_ALPHA_OPACITY_THRESH) {
gp_draw_stroke_buffer_fill(points, totpoints, fill_ink);
}
}
/* --------- 2D Stroke Drawing Helpers --------- */
/* change in parameter list */
static void gp_calc_2d_stroke_fxy(const float pt[3], short sflag, int offsx, int offsy, int winx, int winy, float r_co[2])
@ -318,45 +156,6 @@ static void gp_calc_2d_stroke_fxy(const float pt[3], short sflag, int offsx, int
}
/* ----------- Volumetric Strokes --------------- */
/* draw a 2D buffer stroke in "volumetric" style
* NOTE: the stroke buffer doesn't have any coordinate offsets/transforms
*/
static void gp_draw_stroke_volumetric_buffer(
const tGPspoint *points, int totpoints, short thickness,
short dflag, const float ink[4])
{
/* error checking */
if ((points == NULL) || (totpoints <= 0))
return;
/* check if buffer can be drawn */
if (dflag & (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_ONLYV2D))
return;
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
GPU_enable_program_point_size();
immBegin(GPU_PRIM_POINTS, totpoints);
const tGPspoint *pt = points;
for (int i = 0; i < totpoints; i++, pt++) {
gp_set_tpoint_varying_color(pt, ink, color);
/* TODO: scale based on view transform (zoom level) */
immAttr1f(size, pt->pressure * thickness);
immVertex2f(pos, pt->x, pt->y);
}
immEnd();
immUnbindProgram();
GPU_disable_program_point_size();
}
/* draw a 2D strokes in "volumetric" style */
static void gp_draw_stroke_volumetric_2d(
const bGPDspoint *points, int totpoints, short thickness,
@ -1191,166 +990,6 @@ static void gp_draw_strokes(tGPDdraw *tgpw)
GPU_disable_program_point_size();
}
/* Draw selected verts for strokes being edited */
static void gp_draw_strokes_edit(
bGPdata *gpd, const bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag,
short lflag, const float diff_mat[4][4], float alpha)
{
/* if alpha 0 do not draw */
if (alpha == 0.0f)
return;
const bool no_xray = (dflag & GP_DRAWDATA_NO_XRAY) != 0;
int mask_orig = 0;
/* set up depth masks... */
if (dflag & GP_DRAWDATA_ONLY3D) {
if (no_xray) {
glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig);
glDepthMask(0);
GPU_depth_test(true);
/* first arg is normally rv3d->dist, but this isn't
* available here and seems to work quite well without */
bglPolygonOffset(1.0f, 1.0f);
}
}
GPU_enable_program_point_size();
/* draw stroke verts */
for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
/* check if stroke can be drawn */
if (gp_can_draw_stroke(gps, dflag) == false)
continue;
/* Optimisation: only draw points for selected strokes
* We assume that selected points can only occur in
* strokes that are selected too.
*/
if ((gps->flag & GP_STROKE_SELECT) == 0)
continue;
/* verify color lock */
{
Material *ma = gpd->mat[gps->mat_nr];
MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
if (gp_style != NULL) {
if (gp_style->flag & GP_STYLE_COLOR_HIDE) {
continue;
}
if (((lflag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_STYLE_COLOR_LOCKED)) {
continue;
}
}
}
/* Get size of verts:
* - The selected state needs to be larger than the unselected state so that
* they stand out more.
* - We use the theme setting for size of the unselected verts
*/
float bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
float vsize;
if ((int)bsize > 8) {
vsize = 10.0f;
bsize = 8.0f;
}
else {
vsize = bsize + 2;
}
/* for now, we assume that the base color of the points is not too close to the real color */
/* set color using material */
Material *ma = gpd->mat[gps->mat_nr];
MaterialGPencilStyle *gp_style = (ma) ? ma->gp_style : NULL;
float selectColor[4];
UI_GetThemeColor3fv(TH_GP_VERTEX_SELECT, selectColor);
selectColor[3] = alpha;
GPUVertFormat *format = immVertexFormat();
uint pos; /* specified later */
uint size = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
if (gps->flag & GP_STROKE_3DSPACE) {
pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
}
else {
pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_VARYING_SIZE_VARYING_COLOR);
}
immBegin(GPU_PRIM_POINTS, gps->totpoints);
/* Draw start and end point differently if enabled stroke direction hint */
bool show_direction_hint = (gpd->flag & GP_DATA_SHOW_DIRECTION) && (gps->totpoints > 1);
/* Draw all the stroke points (selected or not) */
bGPDspoint *pt = gps->points;
float fpt[3];
for (int i = 0; i < gps->totpoints; i++, pt++) {
/* size and color first */
if (show_direction_hint && i == 0) {
/* start point in green bigger */
immAttr3f(color, 0.0f, 1.0f, 0.0f);
immAttr1f(size, vsize + 4);
}
else if (show_direction_hint && (i == gps->totpoints - 1)) {
/* end point in red smaller */
immAttr3f(color, 1.0f, 0.0f, 0.0f);
immAttr1f(size, vsize + 1);
}
else if (pt->flag & GP_SPOINT_SELECT) {
immAttr3fv(color, selectColor);
immAttr1f(size, vsize);
}
else if (gp_style) {
immAttr3fv(color, gp_style->stroke_rgba);
immAttr1f(size, bsize);
}
else {
immAttr3f(color, 0.0f, 0.0f, 0.0f);
immAttr1f(size, bsize);
}
/* then position */
if (gps->flag & GP_STROKE_3DSPACE) {
mul_v3_m4v3(fpt, diff_mat, &pt->x);
immVertex3fv(pos, fpt);
}
else {
float co[2];
mul_v3_m4v3(fpt, diff_mat, &pt->x);
gp_calc_2d_stroke_fxy(fpt, gps->flag, offsx, offsy, winx, winy, co);
immVertex2fv(pos, co);
}
}
immEnd();
immUnbindProgram();
}
GPU_disable_program_point_size();
/* clear depth mask */
if (dflag & GP_DRAWDATA_ONLY3D) {
if (no_xray) {
glDepthMask(mask_orig);
GPU_depth_test(false);
bglPolygonOffset(0.0, 0.0);
#if 0
glDisable(GL_POLYGON_OFFSET_LINE);
glPolygonOffset(0, 0);
#endif
}
}
}
/* ----- General Drawing ------ */
@ -1412,114 +1051,6 @@ void ED_gp_draw_fill(tGPDdraw *tgpw)
gp_draw_strokes(tgpw);
}
/* loop over gpencil data layers, drawing them */
static void gp_draw_data_layers(RegionView3D *rv3d,
const Brush *brush, float alpha, Object *ob, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
float diff_mat[4][4];
tGPDdraw tgpw;
tgpw.rv3d = rv3d;
tgpw.depsgraph = NULL; /* XXX: This is not used here */
tgpw.ob = ob;
tgpw.gpd = gpd;
tgpw.gpl = NULL;
tgpw.gpf = NULL;
tgpw.t_gpf = NULL;
tgpw.offsx = offsx;
tgpw.offsy = offsy;
tgpw.winx = winx;
tgpw.winy = winy;
tgpw.dflag = dflag;
tgpw.is_fill_stroke = false;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
/* calculate parent position */
ED_gpencil_parent_location(tgpw.depsgraph, ob, gpd, gpl, diff_mat);
short lthick = brush->size + gpl->line_change;
/* don't draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE)
continue;
/* get frame to draw */
bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra, GP_GETFRAME_USE_PREV);
if (gpf == NULL)
continue;
/* set basic stroke thickness */
GPU_line_width(lthick);
/* Add layer drawing settings to the set of "draw flags"
* NOTE: If the setting doesn't apply, it *must* be cleared,
* as dflag's carry over from the previous layer
*/
/* xray... */
SET_FLAG_FROM_TEST(dflag, gpl->flag & GP_LAYER_NO_XRAY, GP_DRAWDATA_NO_XRAY);
/* volumetric strokes... */
SET_FLAG_FROM_TEST(dflag, gpl->flag & GP_LAYER_VOLUMETRIC, GP_DRAWDATA_VOLUMETRIC);
tgpw.gpl = gpl;
tgpw.gpf = gpf;
tgpw.t_gpf = gpf; // XXX?
tgpw.lthick = gpl->line_change;
tgpw.opacity = gpl->opacity;
copy_v4_v4(tgpw.tintcolor, gpl->tintcolor);
tgpw.onion = false;
tgpw.custonion = false;
copy_m4_m4(tgpw.diff_mat, diff_mat);
/* draw the strokes already in active frame */
gp_draw_strokes(&tgpw);
/* Draw verts of selected strokes
* - when doing OpenGL renders, we don't want to be showing these, as that ends up flickering
* - locked layers can't be edited, so there's no point showing these verts
* as they will have no bearings on what gets edited
* - only show when in editmode, since operators shouldn't work otherwise
* (NOTE: doing it this way means that the toggling editmode shows visible change immediately)
*/
/* XXX: perhaps we don't want to show these when users are drawing... */
if ((G.f & G_FLAG_RENDER_VIEWPORT) == 0 &&
(gpl->flag & GP_LAYER_LOCKED) == 0 &&
(gpd->flag & GP_DATA_STROKE_EDITMODE))
{
gp_draw_strokes_edit(gpd, gpf, offsx, offsy, winx, winy, dflag, gpl->flag, diff_mat, alpha);
}
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke buffer is currently stored in gp-data)
*/
if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
(gpf->flag & GP_FRAME_PAINT))
{
/* Buffer stroke needs to be drawn with a different linestyle
* to help differentiate them from normal strokes.
*
* It should also be noted that sbuffer contains temporary point types
* i.e. tGPspoints NOT bGPDspoints
*/
if (gpd->runtime.mode == GP_STYLE_MODE_DOTS) {
gp_draw_stroke_volumetric_buffer(
gpd->runtime.sbuffer,
gpd->runtime.sbuffer_size, lthick,
dflag, gpd->runtime.scolor);
}
else {
gp_draw_stroke_buffer(
gpd->runtime.sbuffer,
gpd->runtime.sbuffer_size, lthick,
dflag, gpd->runtime.sbuffer_sflag,
gpd->runtime.scolor, gpd->runtime.sfill);
}
}
}
}
/* draw a short status message in the top-right corner */
static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar)
{
@ -1565,129 +1096,3 @@ static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar
GPU_blend(false);
}
}
/* draw grease-pencil datablock */
static void gp_draw_data(RegionView3D *rv3d,
const Brush *brush, float alpha, Object *ob, bGPdata *gpd,
int offsx, int offsy, int winx, int winy, int cfra, int dflag)
{
/* turn on smooth lines (i.e. anti-aliasing) */
GPU_line_smooth(true);
/* XXX: turn on some way of ensuring that the polygon edges get smoothed
* GL_POLYGON_SMOOTH is nasty and shouldn't be used, as it ends up
* creating internal white rays due to the ways it accumulates stuff
*/
/* turn on alpha-blending */
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
/* draw! */
gp_draw_data_layers(rv3d, brush, alpha, ob, gpd, offsx, offsy, winx, winy, cfra, dflag);
/* turn off alpha blending, then smooth lines */
GPU_blend(false); // alpha blending
GPU_line_smooth(false); // smooth lines
}
/* if we have strokes for scenes (3d view)/clips (movie clip editor)
* and objects/tracks, multiple data blocks have to be drawn */
static void gp_draw_data_all(
ViewLayer *view_layer, RegionView3D *rv3d, Scene *scene, bGPdata *gpd,
int offsx, int offsy, int winx, int winy,
int cfra, int dflag, const char UNUSED(spacetype))
{
bGPdata *gpd_source = NULL;
Brush *brush = NULL;
Object *ob = OBACT(view_layer);
if (scene) {
ToolSettings *ts = scene->toolsettings;
brush = BKE_paint_brush(&ts->gp_paint->paint);
if (gpd_source) {
if (brush != NULL) {
gp_draw_data(
rv3d, brush, 1.0f, ob, gpd_source,
offsx, offsy, winx, winy, cfra, dflag);
}
}
}
/* scene/clip data has already been drawn, only object/track data is drawn here
* if gpd_source == gpd, we don't have any object/track data and we can skip */
if (gpd_source == NULL || (gpd_source && gpd_source != gpd)) {
if (brush != NULL) {
gp_draw_data(
rv3d, brush, 1.0f, ob, gpd,
offsx, offsy, winx, winy, cfra, dflag);
}
}
}
/* ----- Grease Pencil Sketches Drawing API ------ */
/* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly
* Note: this gets called twice - first time with only3d=true to draw 3d-strokes,
* second time with only3d=false for screen-aligned strokes */
void ED_gpencil_draw_view3d(
wmWindowManager *wm,
Scene *scene,
ViewLayer *view_layer,
struct Depsgraph *depsgraph,
View3D *v3d,
ARegion *ar,
bool only3d)
{
int dflag = 0;
RegionView3D *rv3d = ar->regiondata;
int offsx, offsy, winx, winy;
/* check that we have grease-pencil stuff to draw */
// XXX: This is the only place that still uses this function
bGPdata *gpd = ED_gpencil_data_get_active_v3d(view_layer, v3d);
if (gpd == NULL) return;
/* when rendering to the offscreen buffer we don't want to
* deal with the camera border, otherwise map the coords to the camera border. */
if ((rv3d->persp == RV3D_CAMOB) && !(G.f & G_FLAG_RENDER_VIEWPORT)) {
rctf rectf;
ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &rectf, true); /* no shift */
offsx = round_fl_to_int(rectf.xmin);
offsy = round_fl_to_int(rectf.ymin);
winx = round_fl_to_int(rectf.xmax - rectf.xmin);
winy = round_fl_to_int(rectf.ymax - rectf.ymin);
}
else {
offsx = 0;
offsy = 0;
winx = ar->winx;
winy = ar->winy;
}
/* set flags */
if (only3d) {
/* 3D strokes/3D space:
* - only 3D space points
* - don't status text either (as it's the wrong space)
*/
dflag |= (GP_DRAWDATA_ONLY3D | GP_DRAWDATA_NOSTATUS);
}
if (v3d->flag2 & V3D_HIDE_OVERLAYS) {
/* don't draw status text when "only render" flag is set */
dflag |= GP_DRAWDATA_NOSTATUS;
}
if ((wm == NULL) || ED_screen_animation_playing(wm)) {
/* don't show onion-skins during animation playback/scrub (i.e. it obscures the poses)
* OpenGL Renders (i.e. final output), or depth buffer (i.e. not real strokes)
*/
dflag |= GP_DRAWDATA_NO_ONIONS;
}
/* draw it! */
gp_draw_data_all(view_layer, rv3d, scene, gpd, offsx, offsy, winx, winy, CFRA, dflag, v3d->spacetype);
}

View File

@ -260,24 +260,6 @@ bool ED_gpencil_data_owner_is_annotation(PointerRNA *owner_ptr)
return ((owner_ptr) && (owner_ptr->type != &RNA_Object));
}
/* -------------------------------------------------------- */
// XXX: this should be removed... We really shouldn't duplicate logic like this!
bGPdata *ED_gpencil_data_get_active_v3d(ViewLayer *view_layer, View3D *v3d)
{
Base *base = view_layer->basact;
bGPdata *gpd = NULL;
/* We have to make sure active object is actually visible and selected, else we must use default scene gpd,
* to be consistent with ED_gpencil_data_get_active's behavior.
*/
if (base && BASE_SELECTED(v3d, base)) {
if (base->object->type == OB_GPENCIL)
gpd = base->object->data;
}
return gpd ? gpd : NULL;
}
/* ******************************************************** */
/* Keyframe Indicator Checks */

View File

@ -135,15 +135,6 @@ void ED_gpencil_strokes_copybuf_free(void);
/* ------------ Grease-Pencil Drawing API ------------------ */
/* drawgpencil.c */
void ED_gpencil_draw_view3d(
struct wmWindowManager *wm,
struct Scene *scene,
struct ViewLayer *view_layer,
struct Depsgraph *depsgraph,
struct View3D *v3d,
struct ARegion *ar,
bool only3d);
void ED_annotation_draw_2dimage(const struct bContext *C);
void ED_annotation_draw_view2d(const struct bContext *C, bool onlyv2d);
void ED_annotation_draw_view3d(

View File

@ -95,6 +95,7 @@
#include "GPU_select.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "GPU_viewport.h"
#include "RE_engine.h"
@ -226,10 +227,25 @@ void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int form
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
}
/* XXX depth reading exception, for code not using gpu offscreen */
static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow.
* Calling this function should be avoided during interactive drawing. */
static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data)
{
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport);
GPUFrameBuffer *tmp_fb = GPU_framebuffer_create();
GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(tmp_fb);
glDisable(GL_SCISSOR_TEST);
glReadPixels(rect->xmin, rect->ymin,
BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
GL_DEPTH_COMPONENT, GL_FLOAT, data);
glEnable(GL_SCISSOR_TEST);
GPU_framebuffer_restore();
GPU_framebuffer_free(tmp_fb);
}
void ED_view3d_select_id_validate_with_select_mode(ViewContext *vc, short select_mode)
@ -745,7 +761,6 @@ void ED_view3d_draw_bgpic_test(
/* *********************** */
/* XXX warning, not using gpu offscreen here */
void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
{
/* clamp rect by region */
@ -796,8 +811,8 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
}
if (d->damaged) {
/* XXX using special function here, it doesn't use the gpu offscreen system */
view3d_opengl_read_Z_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
view3d_opengl_read_Z_pixels(viewport, rect, d->depths);
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
d->damaged = false;
}
@ -863,8 +878,6 @@ float view3d_depth_near(ViewDepths *d)
void ED_view3d_draw_depth_gpencil(
Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d)
{
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
/* Setup view matrix. */
ED_view3d_draw_setup_view(NULL, depsgraph, scene, ar, v3d, NULL, NULL, NULL);
@ -872,7 +885,8 @@ void ED_view3d_draw_depth_gpencil(
GPU_depth_test(true);
ED_gpencil_draw_view3d(NULL, scene, view_layer, depsgraph, v3d, ar, true);
GPUViewport *viewport = WM_draw_region_get_viewport(ar, 0);
DRW_draw_depth_loop_gpencil(depsgraph, ar, v3d, viewport);
GPU_depth_test(false);
}