Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_manager.c
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| #include "draw_manager.h" | #include "draw_manager.h" | ||||
| #include "DNA_camera_types.h" | #include "DNA_camera_types.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_gpencil.h" | |||||
| #include "ED_particle.h" | #include "ED_particle.h" | ||||
| #include "ED_view3d.h" | #include "ED_view3d.h" | ||||
| #include "GPU_draw.h" | #include "GPU_draw.h" | ||||
| #include "GPU_extensions.h" | #include "GPU_extensions.h" | ||||
| #include "GPU_framebuffer.h" | #include "GPU_framebuffer.h" | ||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_uniformbuffer.h" | #include "GPU_uniformbuffer.h" | ||||
| ▲ Show 20 Lines • Show All 1,134 Lines • ▼ Show 20 Lines | switch (mode) { | ||||
| case CTX_MODE_SCULPT: | case CTX_MODE_SCULPT: | ||||
| case CTX_MODE_PAINT_WEIGHT: | case CTX_MODE_PAINT_WEIGHT: | ||||
| case CTX_MODE_PAINT_VERTEX: | case CTX_MODE_PAINT_VERTEX: | ||||
| case CTX_MODE_PAINT_TEXTURE: | case CTX_MODE_PAINT_TEXTURE: | ||||
| /* Should have already been enabled */ | /* Should have already been enabled */ | ||||
| break; | break; | ||||
| case CTX_MODE_OBJECT: | case CTX_MODE_OBJECT: | ||||
| break; | break; | ||||
| case CTX_MODE_GPENCIL_PAINT: | |||||
| case CTX_MODE_GPENCIL_EDIT: | |||||
| case CTX_MODE_GPENCIL_SCULPT: | |||||
| case CTX_MODE_GPENCIL_WEIGHT: | |||||
| break; | |||||
| default: | default: | ||||
| BLI_assert(!"Draw mode invalid"); | BLI_assert(!"Draw mode invalid"); | ||||
| break; | break; | ||||
| } | } | ||||
| /* grease pencil */ | |||||
| use_drw_engine(&draw_engine_gpencil_type); | |||||
| } | } | ||||
| static void drw_engines_enable_from_overlays(int overlay_flag) | static void drw_engines_enable_from_overlays(int overlay_flag) | ||||
| { | { | ||||
| if (overlay_flag) { | if (overlay_flag) { | ||||
| use_drw_engine(&draw_engine_overlay_type); | use_drw_engine(&draw_engine_overlay_type); | ||||
| } | } | ||||
| } | } | ||||
| Show All 16 Lines | static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type) | ||||
| if (DRW_state_draw_support()) { | if (DRW_state_draw_support()) { | ||||
| /* Draw paint modes first so that they are drawn below the wireframes. */ | /* Draw paint modes first so that they are drawn below the wireframes. */ | ||||
| drw_engines_enable_from_paint_mode(mode); | drw_engines_enable_from_paint_mode(mode); | ||||
| drw_engines_enable_from_overlays(v3d->overlay.flag); | drw_engines_enable_from_overlays(v3d->overlay.flag); | ||||
| drw_engines_enable_from_object_mode(); | drw_engines_enable_from_object_mode(); | ||||
| drw_engines_enable_from_mode(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) | static void drw_engines_disable(void) | ||||
| { | { | ||||
| BLI_freelistN(&DST.enabled_engines); | BLI_freelistN(&DST.enabled_engines); | ||||
| } | } | ||||
| static uint DRW_engines_get_hash(void) | static uint DRW_engines_get_hash(void) | ||||
| ▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | void DRW_draw_render_loop_ex( | ||||
| ARegion *ar, View3D *v3d, | ARegion *ar, View3D *v3d, | ||||
| GPUViewport *viewport, | GPUViewport *viewport, | ||||
| const bContext *evil_C) | const bContext *evil_C) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ||||
| RegionView3D *rv3d = ar->regiondata; | 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.draw_ctx.evil_C = evil_C; | ||||
| DST.viewport = viewport; | DST.viewport = viewport; | ||||
| /* Setup viewport */ | /* Setup viewport */ | ||||
| GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash()); | GPU_viewport_engines_data_validate(DST.viewport, DRW_engines_get_hash()); | ||||
| DST.draw_ctx = (DRWContextState){ | DST.draw_ctx = (DRWContextState){ | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | #endif | ||||
| DRW_draw_callbacks_pre_scene(); | DRW_draw_callbacks_pre_scene(); | ||||
| if (DST.draw_ctx.evil_C) { | if (DST.draw_ctx.evil_C) { | ||||
| ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); | ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_PRE_VIEW); | ||||
| } | } | ||||
| drw_engines_draw_scene(); | 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(); | DRW_draw_callbacks_post_scene(); | ||||
| if (DST.draw_ctx.evil_C) { | if (DST.draw_ctx.evil_C) { | ||||
| ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); | ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.ar, REGION_DRAW_POST_VIEW); | ||||
| } | } | ||||
| DRW_state_reset(); | DRW_state_reset(); | ||||
| drw_debug_draw(); | drw_debug_draw(); | ||||
| glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
| drw_engines_draw_text(); | drw_engines_draw_text(); | ||||
| glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
| if (DST.draw_ctx.evil_C) { | if (DST.draw_ctx.evil_C) { | ||||
| /* needed so gizmo isn't obscured */ | /* needed so gizmo isn't obscured */ | ||||
| if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && | if (((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && | ||||
| ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) | ((v3d->gizmo_flag & V3D_GIZMO_HIDE) == 0)) | ||||
| { | { | ||||
| glDisable(GL_DEPTH_TEST); | glDisable(GL_DEPTH_TEST); | ||||
| DRW_draw_gizmo_3d(); | DRW_draw_gizmo_3d(); | ||||
| } | } | ||||
| DRW_draw_region_info(); | 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) { | if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { | ||||
| /* Draw 2D after region info so we can draw on top of the camera passepartout overlay. | /* 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. */ | * 'DRW_draw_region_info' sets the projection in pixel-space. */ | ||||
| DRW_draw_gizmo_2d(); | DRW_draw_gizmo_2d(); | ||||
| glEnable(GL_DEPTH_TEST); | glEnable(GL_DEPTH_TEST); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | if (viewport == NULL) { | ||||
| GPU_viewport_clear_from_offscreen(render_viewport); | GPU_viewport_clear_from_offscreen(render_viewport); | ||||
| GPU_viewport_free(render_viewport); | GPU_viewport_free(render_viewport); | ||||
| } | } | ||||
| /* we need to re-bind (annoying!) */ | /* we need to re-bind (annoying!) */ | ||||
| GPU_offscreen_bind(ofs, false); | 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) | void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) | ||||
| { | { | ||||
| Scene *scene = DEG_get_evaluated_scene(depsgraph); | Scene *scene = DEG_get_evaluated_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph); | ||||
| RenderEngineType *engine_type = engine->type; | RenderEngineType *engine_type = engine->type; | ||||
| DrawEngineType *draw_engine_type = engine_type->draw_engine; | DrawEngineType *draw_engine_type = engine_type->draw_engine; | ||||
| RenderData *r = &scene->r; | RenderData *r = &scene->r; | ||||
| Render *render = engine->re; | Render *render = engine->re; | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) | ||||
| RenderLayer *render_layer = render_result->layers.first; | RenderLayer *render_layer = render_result->layers.first; | ||||
| for (RenderView *render_view = render_result->views.first; | for (RenderView *render_view = render_result->views.first; | ||||
| render_view != NULL; | render_view != NULL; | ||||
| render_view = render_view->next) | render_view = render_view->next) | ||||
| { | { | ||||
| RE_SetActiveRenderView(render, render_view->name); | RE_SetActiveRenderView(render, render_view->name); | ||||
| engine_type->draw_engine->render_to_image(data, engine, render_layer, &render_rect); | 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; | DST.buffer_finish_called = false; | ||||
| } | } | ||||
| RE_engine_end_result(engine, render_result, false, false, false); | RE_engine_end_result(engine, render_result, false, false, false); | ||||
| /* Force cache to reset. */ | /* Force cache to reset. */ | ||||
| drw_viewport_cache_resize(); | drw_viewport_cache_resize(); | ||||
| /* TODO grease pencil */ | |||||
| GPU_viewport_free(DST.viewport); | GPU_viewport_free(DST.viewport); | ||||
| GPU_framebuffer_restore(); | GPU_framebuffer_restore(); | ||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| /* Avoid accidental reuse. */ | /* Avoid accidental reuse. */ | ||||
| drw_state_ensure_not_reused(&DST); | drw_state_ensure_not_reused(&DST); | ||||
| #endif | #endif | ||||
| ▲ Show 20 Lines • Show All 597 Lines • ▼ Show 20 Lines | void DRW_engines_register(void) | ||||
| DRW_engine_register(&draw_engine_motion_path_type); | DRW_engine_register(&draw_engine_motion_path_type); | ||||
| DRW_engine_register(&draw_engine_overlay_type); | DRW_engine_register(&draw_engine_overlay_type); | ||||
| DRW_engine_register(&draw_engine_paint_texture_type); | DRW_engine_register(&draw_engine_paint_texture_type); | ||||
| DRW_engine_register(&draw_engine_paint_vertex_type); | DRW_engine_register(&draw_engine_paint_vertex_type); | ||||
| DRW_engine_register(&draw_engine_paint_weight_type); | DRW_engine_register(&draw_engine_paint_weight_type); | ||||
| DRW_engine_register(&draw_engine_particle_type); | DRW_engine_register(&draw_engine_particle_type); | ||||
| DRW_engine_register(&draw_engine_pose_type); | DRW_engine_register(&draw_engine_pose_type); | ||||
| DRW_engine_register(&draw_engine_sculpt_type); | DRW_engine_register(&draw_engine_sculpt_type); | ||||
| DRW_engine_register(&draw_engine_gpencil_type); | |||||
| /* setup callbacks */ | /* setup callbacks */ | ||||
| { | { | ||||
| /* BKE: mball.c */ | /* BKE: mball.c */ | ||||
| extern void *BKE_mball_batch_cache_dirty_cb; | extern void *BKE_mball_batch_cache_dirty_cb; | ||||
| extern void *BKE_mball_batch_cache_free_cb; | extern void *BKE_mball_batch_cache_free_cb; | ||||
| /* BKE: curve.c */ | /* BKE: curve.c */ | ||||
| extern void *BKE_curve_batch_cache_dirty_cb; | extern void *BKE_curve_batch_cache_dirty_cb; | ||||
| extern void *BKE_curve_batch_cache_free_cb; | extern void *BKE_curve_batch_cache_free_cb; | ||||
| /* BKE: mesh.c */ | /* BKE: mesh.c */ | ||||
| extern void *BKE_mesh_batch_cache_dirty_cb; | extern void *BKE_mesh_batch_cache_dirty_cb; | ||||
| extern void *BKE_mesh_batch_cache_free_cb; | extern void *BKE_mesh_batch_cache_free_cb; | ||||
| /* BKE: lattice.c */ | /* BKE: lattice.c */ | ||||
| extern void *BKE_lattice_batch_cache_dirty_cb; | extern void *BKE_lattice_batch_cache_dirty_cb; | ||||
| extern void *BKE_lattice_batch_cache_free_cb; | extern void *BKE_lattice_batch_cache_free_cb; | ||||
| /* BKE: particle.c */ | /* BKE: particle.c */ | ||||
| extern void *BKE_particle_batch_cache_dirty_cb; | extern void *BKE_particle_batch_cache_dirty_cb; | ||||
| extern void *BKE_particle_batch_cache_free_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_dirty_cb = DRW_mball_batch_cache_dirty; | ||||
| BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; | BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free; | ||||
| BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty; | BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty; | ||||
| BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; | BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free; | ||||
| BKE_mesh_batch_cache_dirty_cb = DRW_mesh_batch_cache_dirty; | BKE_mesh_batch_cache_dirty_cb = DRW_mesh_batch_cache_dirty; | ||||
| BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free; | BKE_mesh_batch_cache_free_cb = DRW_mesh_batch_cache_free; | ||||
| BKE_lattice_batch_cache_dirty_cb = DRW_lattice_batch_cache_dirty; | BKE_lattice_batch_cache_dirty_cb = DRW_lattice_batch_cache_dirty; | ||||
| BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free; | BKE_lattice_batch_cache_free_cb = DRW_lattice_batch_cache_free; | ||||
| BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty; | BKE_particle_batch_cache_dirty_cb = DRW_particle_batch_cache_dirty; | ||||
| BKE_particle_batch_cache_free_cb = DRW_particle_batch_cache_free; | 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; | |||||
| } | } | ||||
| } | } | ||||
| extern struct GPUVertFormat *g_pos_format; /* draw_shgroup.c */ | extern struct GPUVertFormat *g_pos_format; /* draw_shgroup.c */ | ||||
| extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ | ||||
| extern struct GPUTexture *globals_ramp; /* draw_common.c */ | extern struct GPUTexture *globals_ramp; /* draw_common.c */ | ||||
| void DRW_engines_free(void) | void DRW_engines_free(void) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 161 Lines • Show Last 20 Lines | |||||