Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_draw.c
| Show First 20 Lines • Show All 1,876 Lines • ▼ Show 20 Lines | static void view3d_draw_view(const bContext *C, ARegion *ar) | ||||
| /* Only 100% compliant on new spec goes bellow */ | /* Only 100% compliant on new spec goes bellow */ | ||||
| DRW_draw_view(C); | DRW_draw_view(C); | ||||
| } | } | ||||
| void view3d_main_region_draw(const bContext *C, ARegion *ar) | void view3d_main_region_draw(const bContext *C, ARegion *ar) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| WorkSpace *workspace = CTX_wm_workspace(C); | |||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| /* XXX: In the future we should get RE from Layers/Depsgraph */ | |||||
| RenderEngineType *type = RE_engines_find(scene->r.engine); | const char *engine = BKE_render_engine_get(scene, workspace); | ||||
| RenderEngineType *type = RE_engines_find(engine); | |||||
| /* Provisory Blender Internal drawing */ | /* Provisory Blender Internal drawing */ | ||||
| if (type->flag & RE_USE_LEGACY_PIPELINE) { | if (type->flag & RE_USE_LEGACY_PIPELINE) { | ||||
| view3d_main_region_draw_legacy(C, ar); | view3d_main_region_draw_legacy(C, ar); | ||||
| return; | return; | ||||
| } | } | ||||
| if (!rv3d->viewport) { | if (!rv3d->viewport) { | ||||
| Show All 29 Lines | else { /* SCE_VIEWS_FORMAT_MULTIVIEW */ | ||||
| float viewmat[4][4]; | float viewmat[4][4]; | ||||
| Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname); | Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname); | ||||
| 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(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); | view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); | ||||
| } | } | ||||
| } | } | ||||
| void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d) | void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *scene, const WorkSpace *workspace, | ||||
| SceneLayer *sl, View3D *v3d) | |||||
| { | { | ||||
| RenderEngineType *type = RE_engines_find(scene->r.engine); | const char *engine = BKE_render_engine_get(scene, workspace); | ||||
| RenderEngineType *type = RE_engines_find(engine); | |||||
| if (type->flag & RE_USE_LEGACY_PIPELINE) { | if (type->flag & RE_USE_LEGACY_PIPELINE) { | ||||
| /* shadow buffers, before we setup matrices */ | /* shadow buffers, before we setup matrices */ | ||||
| if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) { | if (draw_glsl_material(scene, sl, NULL, v3d, v3d->drawtype)) { | ||||
| VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d); | VP_deprecated_gpu_update_lamps_shadows_world(eval_ctx, scene, v3d); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Show All 11 Lines | else { | ||||
| VP_view3d_draw_background_none(); | VP_view3d_draw_background_none(); | ||||
| } | } | ||||
| } | } | ||||
| /* ED_view3d_draw_offscreen_init should be called before this to initialize | /* ED_view3d_draw_offscreen_init should be called before this to initialize | ||||
| * stuff like shadow buffers | * stuff like shadow buffers | ||||
| */ | */ | ||||
| void ED_view3d_draw_offscreen( | void ED_view3d_draw_offscreen( | ||||
| const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy, | const EvaluationContext *eval_ctx, Scene *scene, const WorkSpace *workspace, SceneLayer *sl, | ||||
| View3D *v3d, ARegion *ar, int winx, int winy, | |||||
| float viewmat[4][4], float winmat[4][4], | float viewmat[4][4], float winmat[4][4], | ||||
| bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, | bool do_bgpic, bool do_sky, bool is_persp, const char *viewname, | ||||
| GPUFX *fx, GPUFXSettings *fx_settings, | GPUFX *fx, GPUFXSettings *fx_settings, | ||||
| GPUOffScreen *ofs) | GPUOffScreen *ofs) | ||||
| { | { | ||||
| bool do_compositing = false; | bool do_compositing = false; | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| Show All 37 Lines | void ED_view3d_draw_offscreen( | ||||
| } | } | ||||
| if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera) | if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera) | ||||
| view3d_stereo3d_setup_offscreen(eval_ctx, scene, v3d, ar, winmat, viewname); | view3d_stereo3d_setup_offscreen(eval_ctx, scene, v3d, ar, winmat, viewname); | ||||
| else | else | ||||
| view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); | view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL); | ||||
| /* main drawing call */ | /* main drawing call */ | ||||
| RenderEngineType *type = RE_engines_find(scene->r.engine); | RenderEngineType *type = RE_engines_find(BKE_render_engine_get(scene, workspace)); | ||||
| if (type->flag & RE_USE_LEGACY_PIPELINE) { | if (type->flag & RE_USE_LEGACY_PIPELINE) { | ||||
| /* framebuffer fx needed, we need to draw offscreen first */ | /* framebuffer fx needed, we need to draw offscreen first */ | ||||
| if (v3d->fx_settings.fx_flag && fx) { | if (v3d->fx_settings.fx_flag && fx) { | ||||
| GPUSSAOSettings *ssao = NULL; | GPUSSAOSettings *ssao = NULL; | ||||
| if (v3d->drawtype < OB_SOLID) { | if (v3d->drawtype < OB_SOLID) { | ||||
| ssao = v3d->fx_settings.ssao; | ssao = v3d->fx_settings.ssao; | ||||
| Show All 26 Lines | if ((v3d->flag2 & V3D_RENDER_SHADOW) == 0) { | ||||
| /* freeing the images again here could be done after the operator runs, leaving for now */ | /* freeing the images again here could be done after the operator runs, leaving for now */ | ||||
| GPU_free_images_anim(); | GPU_free_images_anim(); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* XXX, should take depsgraph as arg */ | /* XXX, should take depsgraph as arg */ | ||||
| Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, sl); | Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, sl); | ||||
| DRW_draw_render_loop_offscreen(depsgraph, ar, v3d, ofs); | DRW_draw_render_loop_offscreen(workspace, depsgraph, ar, v3d, ofs); | ||||
| } | } | ||||
| /* restore size */ | /* restore size */ | ||||
| ar->winx = bwinx; | ar->winx = bwinx; | ||||
| ar->winy = bwiny; | ar->winy = bwiny; | ||||
| ar->winrct = brect; | ar->winrct = brect; | ||||
| gpuPopProjectionMatrix(); | gpuPopProjectionMatrix(); | ||||
| gpuPopMatrix(); | gpuPopMatrix(); | ||||
| UI_Theme_Restore(&theme_state); | UI_Theme_Restore(&theme_state); | ||||
| G.f &= ~G_RENDER_OGL; | G.f &= ~G_RENDER_OGL; | ||||
| } | } | ||||
| /** | /** | ||||
| * Utility func for ED_view3d_draw_offscreen | * Utility func for ED_view3d_draw_offscreen | ||||
| * | * | ||||
| * \param ofs: Optional off-screen buffer, can be NULL. | * \param ofs: Optional off-screen buffer, can be NULL. | ||||
| * (avoids re-creating when doing multiple GL renders). | * (avoids re-creating when doing multiple GL renders). | ||||
| */ | */ | ||||
| ImBuf *ED_view3d_draw_offscreen_imbuf( | ImBuf *ED_view3d_draw_offscreen_imbuf( | ||||
| const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey, | const EvaluationContext *eval_ctx, Scene *scene, const WorkSpace *workspace, SceneLayer *sl, | ||||
| View3D *v3d, ARegion *ar, int sizex, int sizey, | |||||
| unsigned int flag, bool draw_background, | unsigned int flag, bool draw_background, | ||||
| int alpha_mode, int samples, bool full_samples, const char *viewname, | int alpha_mode, int samples, bool full_samples, const char *viewname, | ||||
| /* output vars */ | /* output vars */ | ||||
| GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) | GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) | ||||
| { | { | ||||
| RegionView3D *rv3d = ar->regiondata; | RegionView3D *rv3d = ar->regiondata; | ||||
| const bool draw_sky = (alpha_mode == R_ADDSKY); | const bool draw_sky = (alpha_mode == R_ADDSKY); | ||||
| Show All 12 Lines | ImBuf *ED_view3d_draw_offscreen_imbuf( | ||||
| if (own_ofs) { | if (own_ofs) { | ||||
| /* bind */ | /* bind */ | ||||
| ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, err_out); | ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, err_out); | ||||
| if (ofs == NULL) { | if (ofs == NULL) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| ED_view3d_draw_offscreen_init(eval_ctx, scene, sl, v3d); | ED_view3d_draw_offscreen_init(eval_ctx, scene, workspace, sl, v3d); | ||||
| GPU_offscreen_bind(ofs, true); | GPU_offscreen_bind(ofs, true); | ||||
| /* read in pixels & stamp */ | /* read in pixels & stamp */ | ||||
| ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag); | ImBuf *ibuf = IMB_allocImBuf(sizex, sizey, 32, flag); | ||||
| /* render 3d view */ | /* render 3d view */ | ||||
| if (rv3d->persp == RV3D_CAMOB && v3d->camera) { | if (rv3d->persp == RV3D_CAMOB && v3d->camera) { | ||||
| Show All 25 Lines | else { | ||||
| else { | else { | ||||
| perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); | perspective_m4(winmat, viewplane.xmin, viewplane.xmax, viewplane.ymin, viewplane.ymax, clipsta, clipend); | ||||
| } | } | ||||
| } | } | ||||
| if ((samples && full_samples) == 0) { | if ((samples && full_samples) == 0) { | ||||
| /* Single-pass render, common case */ | /* Single-pass render, common case */ | ||||
| ED_view3d_draw_offscreen( | ED_view3d_draw_offscreen( | ||||
| eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, | eval_ctx, scene, workspace, sl, v3d, ar, sizex, sizey, NULL, winmat, | ||||
| draw_background, draw_sky, !is_ortho, viewname, | draw_background, draw_sky, !is_ortho, viewname, | ||||
| fx, &fx_settings, ofs); | fx, &fx_settings, ofs); | ||||
| if (ibuf->rect_float) { | if (ibuf->rect_float) { | ||||
| GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float); | GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float); | ||||
| } | } | ||||
| else if (ibuf->rect) { | else if (ibuf->rect) { | ||||
| GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); | GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling. | /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling. | ||||
| * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */ | * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */ | ||||
| static float jit_ofs[32][2]; | static float jit_ofs[32][2]; | ||||
| float winmat_jitter[4][4]; | float winmat_jitter[4][4]; | ||||
| /* use imbuf as temp storage, before writing into it from accumulation buffer */ | /* use imbuf as temp storage, before writing into it from accumulation buffer */ | ||||
| unsigned char *rect_temp = ibuf->rect ? (void *)ibuf->rect : (void *)ibuf->rect_float; | unsigned char *rect_temp = ibuf->rect ? (void *)ibuf->rect : (void *)ibuf->rect_float; | ||||
| unsigned int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int[4]), "accum1"); | unsigned int *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(int[4]), "accum1"); | ||||
| BLI_jitter_init(jit_ofs, samples); | BLI_jitter_init(jit_ofs, samples); | ||||
| /* first sample buffer, also initializes 'rv3d->persmat' */ | /* first sample buffer, also initializes 'rv3d->persmat' */ | ||||
| ED_view3d_draw_offscreen( | ED_view3d_draw_offscreen( | ||||
| eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat, | eval_ctx, scene, workspace, sl, v3d, ar, sizex, sizey, NULL, winmat, | ||||
| draw_background, draw_sky, !is_ortho, viewname, | draw_background, draw_sky, !is_ortho, viewname, | ||||
| fx, &fx_settings, ofs); | fx, &fx_settings, ofs); | ||||
| GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); | GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); | ||||
| unsigned i = sizex * sizey * 4; | unsigned i = sizex * sizey * 4; | ||||
| while (i--) { | while (i--) { | ||||
| accum_buffer[i] = rect_temp[i]; | accum_buffer[i] = rect_temp[i]; | ||||
| } | } | ||||
| /* skip the first sample */ | /* skip the first sample */ | ||||
| for (int j = 1; j < samples; j++) { | for (int j = 1; j < samples; j++) { | ||||
| copy_m4_m4(winmat_jitter, winmat); | copy_m4_m4(winmat_jitter, winmat); | ||||
| window_translate_m4( | window_translate_m4( | ||||
| winmat_jitter, rv3d->persmat, | winmat_jitter, rv3d->persmat, | ||||
| (jit_ofs[j][0] * 2.0f) / sizex, | (jit_ofs[j][0] * 2.0f) / sizex, | ||||
| (jit_ofs[j][1] * 2.0f) / sizey); | (jit_ofs[j][1] * 2.0f) / sizey); | ||||
| ED_view3d_draw_offscreen( | ED_view3d_draw_offscreen( | ||||
| eval_ctx, scene, sl, v3d, ar, sizex, sizey, NULL, winmat_jitter, | eval_ctx, scene, workspace, sl, v3d, ar, sizex, sizey, NULL, winmat_jitter, | ||||
| draw_background, draw_sky, !is_ortho, viewname, | draw_background, draw_sky, !is_ortho, viewname, | ||||
| fx, &fx_settings, ofs); | fx, &fx_settings, ofs); | ||||
| GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); | GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, rect_temp); | ||||
| i = sizex * sizey * 4; | i = sizex * sizey * 4; | ||||
| while (i--) { | while (i--) { | ||||
| accum_buffer[i] += rect_temp[i]; | accum_buffer[i] += rect_temp[i]; | ||||
| } | } | ||||
| Show All 34 Lines | |||||
| * Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf) | * Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf) | ||||
| * | * | ||||
| * \param ofs: Optional off-screen buffer can be NULL. | * \param ofs: Optional off-screen buffer can be NULL. | ||||
| * (avoids re-creating when doing multiple GL renders). | * (avoids re-creating when doing multiple GL renders). | ||||
| * | * | ||||
| * \note used by the sequencer | * \note used by the sequencer | ||||
| */ | */ | ||||
| ImBuf *ED_view3d_draw_offscreen_imbuf_simple( | ImBuf *ED_view3d_draw_offscreen_imbuf_simple( | ||||
| const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *camera, int width, int height, | const EvaluationContext *eval_ctx, Scene *scene, const WorkSpace *workspace, SceneLayer *sl, | ||||
| Object *camera, int width, int height, | |||||
| unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, | unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background, | ||||
| int alpha_mode, int samples, bool full_samples, const char *viewname, | int alpha_mode, int samples, bool full_samples, const char *viewname, | ||||
| GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) | GPUFX *fx, GPUOffScreen *ofs, char err_out[256]) | ||||
| { | { | ||||
| View3D v3d = {NULL}; | View3D v3d = {NULL}; | ||||
| ARegion ar = {NULL}; | ARegion ar = {NULL}; | ||||
| RegionView3D rv3d = {{{0}}}; | RegionView3D rv3d = {{{0}}}; | ||||
| Show All 37 Lines | invert_m4_m4(rv3d.viewmat, rv3d.viewinv); | ||||
| v3d.far = params.clipend; | v3d.far = params.clipend; | ||||
| v3d.lens = params.lens; | v3d.lens = params.lens; | ||||
| } | } | ||||
| mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); | mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat); | ||||
| invert_m4_m4(rv3d.persinv, rv3d.viewinv); | invert_m4_m4(rv3d.persinv, rv3d.viewinv); | ||||
| return ED_view3d_draw_offscreen_imbuf( | return ED_view3d_draw_offscreen_imbuf( | ||||
| eval_ctx, scene, sl, &v3d, &ar, width, height, flag, | eval_ctx, scene, workspace, sl, &v3d, &ar, width, height, flag, | ||||
| draw_background, alpha_mode, samples, full_samples, viewname, | draw_background, alpha_mode, samples, full_samples, viewname, | ||||
| fx, ofs, err_out); | fx, ofs, err_out); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| ▲ Show 20 Lines • Show All 93 Lines • Show Last 20 Lines | |||||