Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_draw.c
- This file was copied to source/blender/viewport/intern/blender_viewport/blender_viewport.c.
| Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| #include "VP_engine_API.h" | |||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "view3d_intern.h" /* own include */ | #include "view3d_intern.h" /* own include */ | ||||
| /* prototypes */ | |||||
| static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth); | |||||
| typedef struct DrawData { | typedef struct DrawData { | ||||
| rcti border_rect; | rcti border_rect; | ||||
| bool render_border; | bool render_border; | ||||
| bool clip_border; | bool clip_border; | ||||
| bool is_render; | bool is_render; | ||||
| } DrawData; | } DrawData; | ||||
| static void view3d_draw_data_init(const bContext *C, ARegion *ar, DrawData *draw_data) | |||||
| { | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| draw_data->is_render = (v3d->drawtype == OB_RENDER); | |||||
| draw_data->render_border = ED_view3d_calc_render_border(scene, v3d, ar, &draw_data->border_rect); | |||||
| draw_data->clip_border = (draw_data->render_border && !BLI_rcti_compare(&ar->drawrct, &draw_data->border_rect)); | |||||
| } | |||||
| /* ******************** general functions ***************** */ | /* ******************** general functions ***************** */ | ||||
| static bool use_depth_doit(Scene *scene, View3D *v3d) | static bool use_depth_doit(Scene *scene, View3D *v3d) | ||||
| { | { | ||||
| if (v3d->drawtype > OB_WIRE) | if (v3d->drawtype > OB_WIRE) | ||||
| return true; | return true; | ||||
| /* special case (depth for wire color) */ | /* special case (depth for wire color) */ | ||||
| if (v3d->drawtype <= OB_WIRE) { | if (v3d->drawtype <= OB_WIRE) { | ||||
| if (scene->obedit && scene->obedit->type == OB_MESH) { | if (scene->obedit && scene->obedit->type == OB_MESH) { | ||||
| Mesh *me = scene->obedit->data; | Mesh *me = scene->obedit->data; | ||||
| if (me->drawflag & ME_DRAWEIGHT) { | if (me->drawflag & ME_DRAWEIGHT) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static bool use_depth(const bContext *C) | |||||
| { | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| return use_depth_doit(scene, v3d); | |||||
| } | |||||
| /** | /** | ||||
| * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore | * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore | ||||
| */ | */ | ||||
| void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) | void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]) | ||||
| { | { | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| rctf cameraborder; | rctf cameraborder; | ||||
| ▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | else { /* SCE_VIEWS_FORMAT_MULTIVIEW */ | ||||
| BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat); | BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat); | ||||
| view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL); | view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL); | ||||
| v3d->camera = view_ob; | v3d->camera = view_ob; | ||||
| BLI_unlock_thread(LOCK_VIEW3D); | BLI_unlock_thread(LOCK_VIEW3D); | ||||
| } | } | ||||
| } | } | ||||
| /* ******************** offline engine ***************** */ | |||||
| static bool view3d_draw_render_draw(const bContext *C, Scene *scene, | |||||
| ARegion *ar, View3D *v3d, | |||||
| bool clip_border, const rcti *border_rect) | |||||
| { | |||||
| RegionView3D *rv3d = ar->regiondata; | |||||
| RenderEngineType *type; | |||||
| GLint scissor[4]; | |||||
| /* create render engine */ | |||||
| if (!rv3d->render_engine) { | |||||
| RenderEngine *engine; | |||||
| type = RE_engines_find(scene->r.engine); | |||||
| if (!(type->view_update && type->view_draw)) | |||||
| return false; | |||||
| engine = RE_engine_create_ex(type, true); | |||||
| engine->tile_x = scene->r.tilex; | |||||
| engine->tile_y = scene->r.tiley; | |||||
| type->view_update(engine, C); | |||||
| rv3d->render_engine = engine; | |||||
| } | |||||
| /* background draw */ | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glPushMatrix(); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glPushMatrix(); | |||||
| ED_region_pixelspace(ar); | |||||
| if (clip_border) { | |||||
| /* for border draw, we only need to clear a subset of the 3d view */ | |||||
| if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) { | |||||
| glGetIntegerv(GL_SCISSOR_BOX, scissor); | |||||
| glScissor(border_rect->xmin, border_rect->ymin, | |||||
| BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect)); | |||||
| } | |||||
| else { | |||||
| return false; | |||||
| } | |||||
| } | |||||
| glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | |||||
| /* don't change depth buffer */ | |||||
| glClear(GL_COLOR_BUFFER_BIT); | |||||
| /* render result draw */ | |||||
| type = rv3d->render_engine->type; | |||||
| type->view_draw(rv3d->render_engine, C); | |||||
| if (clip_border) { | |||||
| /* restore scissor as it was before */ | |||||
| glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); | |||||
| } | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glPopMatrix(); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glPopMatrix(); | |||||
| return true; | |||||
| } | |||||
| /* ******************** solid plates ***************** */ | |||||
| /** | |||||
| * | |||||
| */ | |||||
| static void view3d_draw_background(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| UI_ThemeClearColor(TH_HIGH_GRAD); | |||||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |||||
| } | |||||
| /** | |||||
| * | |||||
| */ | |||||
| static void view3d_draw_render_solid_surfaces(const bContext *C, ARegion *ar, const bool run_screen_shaders) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| draw_all_objects(C, ar, false, use_depth(C)); | |||||
| } | |||||
| /** | |||||
| * | |||||
| */ | |||||
| static void view3d_draw_render_transparent_surfaces(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /** | |||||
| * | |||||
| */ | |||||
| static void view3d_draw_post_draw(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /* ******************** geometry overlay ***************** */ | |||||
| /** | |||||
| * Front/back wire frames | |||||
| */ | |||||
| static void view3d_draw_wire_plates(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /** | |||||
| * Special treatment for selected objects | |||||
| */ | |||||
| static void view3d_draw_outline_plates(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /* ******************** other elements ***************** */ | /* ******************** other elements ***************** */ | ||||
| #define DEBUG_GRID 0 | #define DEBUG_GRID 0 | ||||
| static void gridline_range(double x0, double dx, double max, int* first_out, int* count_out) | static void gridline_range(double x0, double dx, double max, int* first_out, int* count_out) | ||||
| { | { | ||||
| /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y | /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y | ||||
| ▲ Show 20 Lines • Show All 471 Lines • ▼ Show 20 Lines | float ED_scene_grid_scale(Scene *scene, const char **grid_unit) | ||||
| return 1.0f; | return 1.0f; | ||||
| } | } | ||||
| float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) | float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit) | ||||
| { | { | ||||
| return v3d->grid * ED_scene_grid_scale(scene, grid_unit); | return v3d->grid * ED_scene_grid_scale(scene, grid_unit); | ||||
| } | } | ||||
| /** | |||||
| * | |||||
| */ | |||||
| static void view3d_draw_grid(const bContext *C, ARegion *ar) | |||||
| { | |||||
| /* TODO viewport | |||||
| * Missing is the flags to check whether to draw it | |||||
| * for now now we are using the flags in v3d itself. | |||||
| * | |||||
| * Also for now always assume depth is there, so we | |||||
| * draw on top of it. | |||||
| */ | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| RegionView3D *rv3d = ar->regiondata; | |||||
| const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO); | |||||
| const char *grid_unit = NULL; | |||||
| /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override | |||||
| * objects if done last */ | |||||
| /* needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views. */ | |||||
| rv3d->gridview = ED_view3d_grid_scale(scene, v3d, grid_unit); | |||||
| glEnable(GL_DEPTH_TEST); | |||||
| if (!draw_floor) { | |||||
| ED_region_pixelspace(ar); | |||||
| *(&grid_unit) = NULL; /* drawgrid need this to detect/affect smallest valid unit... */ | |||||
| drawgrid(&scene->unit, ar, v3d, &grid_unit); | |||||
| glMatrixMode(GL_PROJECTION); | |||||
| glLoadMatrixf(rv3d->winmat); | |||||
| glMatrixMode(GL_MODELVIEW); | |||||
| glLoadMatrixf(rv3d->viewmat); | |||||
| } | |||||
| else { | |||||
| drawfloor(scene, v3d, &grid_unit, false); | |||||
| } | |||||
| glDisable(GL_DEPTH_TEST); | |||||
| } | |||||
| /* ******************** view loop ***************** */ | /* ******************** view loop ***************** */ | ||||
| /** | void view3d_main_region_draw(const bContext *C, ARegion *UNUSED(ar)) | ||||
| * Set the correct matrices | |||||
| */ | |||||
| static void view3d_draw_setup_view(const bContext *C, ARegion *ar) | |||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| RegionView3D *rv3d = ar->regiondata; | |||||
| /* setup the view matrix */ | |||||
| if (view3d_stereo3d_active(C, scene, v3d, rv3d)) | |||||
| view3d_stereo3d_setup(scene, v3d, ar); | |||||
| else | |||||
| view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL); | |||||
| } | |||||
| static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth) | VP_engine_render(v3d->viewport_engine, C); | ||||
| { | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| Base *base; | |||||
| if (only_depth) | |||||
| glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | |||||
| if (only_depth || use_depth) { | |||||
| glEnable(GL_DEPTH_TEST); | |||||
| v3d->zbuf = true; | |||||
| } | |||||
| for (base = scene->base.first; base; base = base->next) { | |||||
| if (v3d->lay & base->lay) { | |||||
| /* dupli drawing */ | |||||
| if (base->object->transflag & OB_DUPLI) | |||||
| draw_dupli_objects(scene, ar, v3d, base); | |||||
| draw_object(scene, ar, v3d, base, 0); | |||||
| } | |||||
| } | |||||
| if (only_depth) | |||||
| glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |||||
| glDisable(GL_DEPTH_TEST); | |||||
| } | |||||
| /** | |||||
| * Draw only the scene depth buffer | |||||
| */ | |||||
| static void draw_depth_buffer(const bContext *C, ARegion *ar) | |||||
| { | |||||
| draw_all_objects(C, ar, true, true); | |||||
| } | |||||
| /** | |||||
| * Required if the shaders need it or external engines | |||||
| * (e.g., Cycles requires depth buffer handled separately). | |||||
| */ | |||||
| static void view3d_draw_prerender_buffers(const bContext *C, ARegion *ar, DrawData *draw_data) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| if (draw_data->is_render && (!draw_data->clip_border)) { | |||||
| draw_depth_buffer(C, ar); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Draw all the plates that will fill the RGBD buffer | |||||
| */ | |||||
| static void view3d_draw_solid_plates(const bContext *C, ARegion *ar, DrawData *draw_data) | |||||
| { | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| /* realtime plates */ | |||||
| if ((!draw_data->is_render) || draw_data->clip_border) { | |||||
| view3d_draw_background(C); | |||||
| view3d_draw_render_solid_surfaces(C, ar, true); | |||||
| view3d_draw_render_transparent_surfaces(C); | |||||
| view3d_draw_post_draw(C); | |||||
| } | |||||
| /* offline plates*/ | |||||
| if (draw_data->is_render) { | |||||
| view3d_draw_render_draw(C, scene, ar, v3d, draw_data->clip_border, &draw_data->border_rect); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Wires, outline, ... | |||||
| */ | |||||
| static void view3d_draw_geometry_overlay(const bContext *C) | |||||
| { | |||||
| view3d_draw_wire_plates(C); | |||||
| view3d_draw_outline_plates(C); | |||||
| } | |||||
| /** | |||||
| * Empties, lamps, parent lines, grid, ... | |||||
| */ | |||||
| static void view3d_draw_other_elements(const bContext *C, ARegion *ar) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| view3d_draw_grid(C, ar); | |||||
| } | |||||
| /** | |||||
| * Paint brushes, armatures, ... | |||||
| */ | |||||
| static void view3d_draw_tool_ui(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /** | |||||
| * Blueprint images | |||||
| */ | |||||
| static void view3d_draw_reference_images(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /** | |||||
| * Grease Pencil | |||||
| */ | |||||
| static void view3d_draw_grease_pencil(const bContext *C) | |||||
| { | |||||
| /* TODO viewport */ | |||||
| } | |||||
| /** | |||||
| * This could run once per view, or even in parallel | |||||
| * for each of them. What is a "view"? | |||||
| * - a viewport with the camera elsewhere | |||||
| * - left/right stereo | |||||
| * - panorama / fisheye individual cubemap faces | |||||
| */ | |||||
| static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data) | |||||
| { | |||||
| /* TODO - Technically this should be drawn to a few FBO, so we can handle | |||||
| * compositing better, but for now this will get the ball rolling (dfelinto) */ | |||||
| view3d_draw_setup_view(C, ar); | |||||
| view3d_draw_prerender_buffers(C, ar, draw_data); | |||||
| view3d_draw_solid_plates(C, ar, draw_data); | |||||
| view3d_draw_geometry_overlay(C); | |||||
| view3d_draw_other_elements(C, ar); | |||||
| view3d_draw_tool_ui(C); | |||||
| view3d_draw_reference_images(C); | |||||
| view3d_draw_grease_pencil(C); | |||||
| } | |||||
| void view3d_main_region_draw(const bContext *C, ARegion *ar) | |||||
| { | |||||
| View3D *v3d = CTX_wm_view3d(C); | |||||
| if (IS_VIEWPORT_LEGACY(v3d)) { | |||||
| view3d_main_region_draw_legacy(C, ar); | |||||
| return; | |||||
| } | |||||
| /* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c | |||||
| * before we even call the drawing routine, but let's move on for now (dfelinto) | |||||
| * but this is a provisory way to start seeing things in the viewport */ | |||||
| DrawData draw_data; | |||||
| view3d_draw_data_init(C, ar, &draw_data); | |||||
| view3d_draw_view(C, ar, &draw_data); | |||||
| v3d->flag |= V3D_INVALID_BACKBUF; | v3d->flag |= V3D_INVALID_BACKBUF; | ||||
| } | } | ||||
| /* ******************** legacy interface ***************** */ | /* ******************** legacy interface ***************** */ | ||||
| /** | /** | ||||
| * This will be removed once the viewport gets replaced | * This will be removed once the viewport gets replaced | ||||
| * meanwhile it should keep the old viewport working. | * meanwhile it should keep the old viewport working. | ||||
| Show All 22 Lines | |||||
| void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar) | void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar) | ||||
| { | { | ||||
| view3d_stereo3d_setup(scene, v3d, ar); | view3d_stereo3d_setup(scene, v3d, ar); | ||||
| } | } | ||||
| bool VP_legacy_use_depth(Scene *scene, View3D *v3d) | bool VP_legacy_use_depth(Scene *scene, View3D *v3d) | ||||
| { | { | ||||
| return use_depth_doit(scene, v3d); | return use_depth_doit(scene, v3d); | ||||
| } | } | ||||
| No newline at end of file | |||||