diff options
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 60 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 4 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 145 |
5 files changed, 209 insertions, 4 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 0db16ab5472..abba8d3ce91 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -136,6 +136,7 @@ typedef char DRWViewportEmptyList; + typedef struct DrawEngineDataSize { int fbl_len; int txl_len; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index bdfa3211f7c..ac84a847a1b 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -107,6 +107,7 @@ static struct DRWShapeCache { GPUBatch *drw_particle_cross; GPUBatch *drw_particle_circle; GPUBatch *drw_particle_axis; + GPUBatch *drw_gpencil_axes; } SHC = {NULL}; void DRW_shape_cache_free(void) @@ -551,12 +552,67 @@ GPUBatch *DRW_cache_screenspace_circle_get(void) #undef CIRCLE_RESOL } -/** \} */ +/* Grease Pencil object */ +GPUBatch *DRW_cache_gpencil_axes_get(void) +{ + if (!SHC.drw_gpencil_axes) { + int axis; + float v1[3] = { 0.0f, 0.0f, 0.0f }; + float v2[3] = { 0.0f, 0.0f, 0.0f }; + + /* cube data */ + const GLfloat verts[8][3] = { + { -0.25f, -0.25f, -0.25f }, + { -0.25f, -0.25f, 0.25f }, + { -0.25f, 0.25f, -0.25f }, + { -0.25f, 0.25f, 0.25f }, + { 0.25f, -0.25f, -0.25f }, + { 0.25f, -0.25f, 0.25f }, + { 0.25f, 0.25f, -0.25f }, + { 0.25f, 0.25f, 0.25f } + }; + + const GLubyte indices[24] = { 0, 1, 1, 3, 3, 2, 2, 0, 0, 4, 4, 5, 5, 7, 7, 6, 6, 4, 1, 5, 3, 7, 2, 6 }; + + /* Position Only 3D format */ + static GPUVertFormat format = { 0 }; + static uint pos_id; + if (format.attr_len == 0) { + pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + + GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); + + /* alloc 30 elements for cube and 3 axis */ + GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(indices) + 6); + + /* draw axis */ + for (axis = 0; axis < 3; axis++) { + v1[axis] = 1.0f; + v2[axis] = -1.0f; + + GPU_vertbuf_attr_set(vbo, pos_id, axis * 2, v1); + GPU_vertbuf_attr_set(vbo, pos_id, axis * 2 + 1, v2); + + /* reset v1 & v2 to zero for next axis */ + v1[axis] = v2[axis] = 0.0f; + } + + /* draw cube */ + for (int i = 0; i < 24; ++i) { + GPU_vertbuf_attr_set(vbo, pos_id, i + 6, verts[indices[i]]); + } + + SHC.drw_gpencil_axes = GPU_batch_create(GPU_PRIM_LINES, vbo, NULL); + } + return SHC.drw_gpencil_axes; +} + /* -------------------------------------------------------------------- */ /** \name Common Object API - * \{ */ +* \{ */ GPUBatch *DRW_cache_object_wire_outline_get(Object *ob) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 129c0252f30..7d0996b3059 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -82,6 +82,9 @@ struct GPUBatch *DRW_cache_field_vortex_get(void); struct GPUBatch *DRW_cache_field_tube_limit_get(void); struct GPUBatch *DRW_cache_field_cone_limit_get(void); +/* Grease Pencil */ +struct GPUBatch *DRW_cache_gpencil_axes_get(void); + /* Lamps */ struct GPUBatch *DRW_cache_lamp_get(void); struct GPUBatch *DRW_cache_lamp_shadows_get(void); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index eeb7b1c41ee..d4dbe5db80d 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -41,6 +41,7 @@ struct Curve; struct Lattice; struct Mesh; struct MetaBall; +struct bGPdata; /* Expose via BKE callbacks */ void DRW_mball_batch_cache_dirty(struct MetaBall *mb, int mode); @@ -58,6 +59,9 @@ void DRW_lattice_batch_cache_free(struct Lattice *lt); void DRW_particle_batch_cache_dirty(struct ParticleSystem *psys, int mode); void DRW_particle_batch_cache_free(struct ParticleSystem *psys); +void DRW_gpencil_batch_cache_dirty(struct bGPdata *gpd); +void DRW_gpencil_batch_cache_free(struct bGPdata *gpd); + /* Curve */ struct GPUBatch *DRW_curve_batch_cache_get_wire_edge(struct Curve *cu, struct CurveCache *ob_curve_cache); struct GPUBatch *DRW_curve_batch_cache_get_normal_edge( diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 714edc23719..e6e20934283 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -48,6 +48,7 @@ #include "ED_space_api.h" #include "ED_screen.h" +#include "ED_gpencil.h" #include "ED_particle.h" #include "ED_view3d.h" @@ -1222,10 +1223,17 @@ static void drw_engines_enable_from_mode(int mode) break; case CTX_MODE_OBJECT: break; + case CTX_MODE_GPENCIL_PAINT: + case CTX_MODE_GPENCIL_EDIT: + case CTX_MODE_GPENCIL_SCULPT: + case CTX_MODE_GPENCIL_WEIGHT: + break; default: BLI_assert(!"Draw mode invalid"); break; } + /* grease pencil */ + use_drw_engine(&draw_engine_gpencil_type); } static void drw_engines_enable_from_overlays(int overlay_flag) @@ -1258,6 +1266,10 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t drw_engines_enable_from_object_mode(); drw_engines_enable_from_mode(mode); } + else { + /* if gpencil must draw the strokes, but not the object */ + drw_engines_enable_from_mode(mode); + } } static void drw_engines_disable(void) @@ -1377,6 +1389,7 @@ void DRW_draw_render_loop_ex( Scene *scene = DEG_get_evaluated_scene(depsgraph); ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); RegionView3D *rv3d = ar->regiondata; + bool do_annotations = (((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0)); DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; @@ -1471,6 +1484,17 @@ void DRW_draw_render_loop_ex( drw_engines_draw_scene(); + /* annotations - temporary drawing buffer (3d space) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (do_annotations)) + { + glDisable(GL_DEPTH_TEST); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, true); + glEnable(GL_DEPTH_TEST); + } + DRW_draw_callbacks_post_scene(); if (DST.draw_ctx.evil_C) { ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); @@ -1495,6 +1519,17 @@ void DRW_draw_render_loop_ex( DRW_draw_region_info(); + /* annotations - temporary drawing buffer (screenspace) */ + /* XXX: Or should we use a proper draw/overlay engine for this case? */ + if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && + (do_annotations)) + { + glDisable(GL_DEPTH_TEST); + /* XXX: as scene->gpd is not copied for COW yet */ + ED_gpencil_draw_view3d_annotations(DEG_get_input_scene(depsgraph), depsgraph, v3d, ar, false); + glEnable(GL_DEPTH_TEST); + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. * 'DRW_draw_region_info' sets the projection in pixel-space. */ @@ -1583,6 +1618,105 @@ void DRW_draw_render_loop_offscreen( GPU_offscreen_bind(ofs, false); } +/* helper to check if exit object type to render */ +static bool DRW_render_check_object_type(struct Depsgraph *depsgraph, short obtype) +{ + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) + { + if ((ob->type == obtype) && (DRW_check_object_visible_within_active_context(ob))) { + return true; + } + } + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END + + return false; +} + +static void DRW_render_gpencil_to_image(RenderEngine *engine, struct Depsgraph *depsgraph, struct RenderLayer *render_layer, const rcti *rect) +{ + if (draw_engine_gpencil_type.render_to_image) { + if (DRW_render_check_object_type(depsgraph, OB_GPENCIL)) { + ViewportEngineData *gpdata = drw_viewport_engine_data_ensure(&draw_engine_gpencil_type); + draw_engine_gpencil_type.render_to_image(gpdata, engine, render_layer, rect); + } + } +} + +void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph) +{ + /* This function is only valid for Cycles + * Eevee done all work in the Eevee render directly. + * Maybe it can be done equal for both engines? + */ + if (STREQ(engine->type->name, "Eevee")) { + return; + } + + Scene *scene = DEG_get_evaluated_scene(depsgraph); + ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); + RenderEngineType *engine_type = engine->type; + RenderData *r = &scene->r; + Render *render = engine->re; + /* Changing Context */ + /* GPXX Review this context */ + DRW_opengl_context_enable(); + /* Reset before using it. */ + drw_state_prepare_clean_for_draw(&DST); + DST.options.is_image_render = true; + DST.options.is_scene_render = true; + DST.options.draw_background = scene->r.alphamode == R_ADDSKY; + DST.buffer_finish_called = true; + + DST.draw_ctx = (DRWContextState) { + .scene = scene, .view_layer = view_layer, + .engine_type = engine_type, + .depsgraph = depsgraph, .object_mode = OB_MODE_OBJECT, + }; + drw_context_state_init(); + + DST.viewport = GPU_viewport_create(); + const int size[2] = { (r->size * r->xsch) / 100, (r->size * r->ysch) / 100 }; + GPU_viewport_size_set(DST.viewport, size); + + drw_viewport_var_init(); + + /* set default viewport */ + gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT); + glDisable(GL_SCISSOR_TEST); + glViewport(0, 0, size[0], size[1]); + + /* Main rendering. */ + rctf view_rect; + rcti render_rect; + RE_GetViewPlane(render, &view_rect, &render_rect); + if (BLI_rcti_is_empty(&render_rect)) { + BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]); + } + + RenderResult *render_result = RE_engine_get_result(engine); + RenderLayer *render_layer = render_result->layers.first; + + DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); + + /* Force cache to reset. */ + drw_viewport_cache_resize(); + GPU_viewport_free(DST.viewport); + DRW_state_reset(); + + glDisable(GL_DEPTH_TEST); + + /* Restore Drawing area. */ + gpuPopAttrib(); + glEnable(GL_SCISSOR_TEST); + GPU_framebuffer_restore(); + + /* Changing Context */ + /* GPXX Review this context */ + DRW_opengl_context_disable(); + + DST.buffer_finish_called = false; +} + void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) { Scene *scene = DEG_get_evaluated_scene(depsgraph); @@ -1663,6 +1797,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) { RE_SetActiveRenderView(render, render_view->name); engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect); + /* grease pencil: render result is merged in the previous render result. */ + DRW_render_gpencil_to_image(engine, depsgraph, render_layer, &render_rect); DST.buffer_finish_called = false; } @@ -1671,8 +1807,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) /* Force cache to reset. */ drw_viewport_cache_resize(); - /* TODO grease pencil */ - GPU_viewport_free(DST.viewport); GPU_framebuffer_restore(); @@ -2286,6 +2420,7 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_particle_type); DRW_engine_register(&draw_engine_pose_type); DRW_engine_register(&draw_engine_sculpt_type); + DRW_engine_register(&draw_engine_gpencil_type); /* setup callbacks */ { @@ -2304,6 +2439,9 @@ void DRW_engines_register(void) /* BKE: particle.c */ extern void *BKE_particle_batch_cache_dirty_cb; extern void *BKE_particle_batch_cache_free_cb; + /* BKE: gpencil.c */ + extern void *BKE_gpencil_batch_cache_dirty_cb; + extern void *BKE_gpencil_batch_cache_free_cb; BKE_mball_batch_cache_dirty_cb = DRW_mball_batch_cache_dirty; BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; @@ -2319,6 +2457,9 @@ void DRW_engines_register(void) BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty; BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free; + + BKE_gpencil_batch_cache_dirty_cb = DRW_gpencil_batch_cache_dirty; + BKE_gpencil_batch_cache_free_cb = DRW_gpencil_batch_cache_free; } } |