DRW: Add viewport argument to DRW_draw_render_loop_offscreen

This way we can have persistent data accross different calls.
This commit is contained in:
2018-01-05 10:18:44 +01:00
parent 9be32ac5fe
commit 9a00d57371
5 changed files with 34 additions and 14 deletions

View File

@@ -44,6 +44,7 @@ struct ViewportEngineData;
struct View3D;
struct rcti;
struct GPUOffScreen;
struct GPUViewport;
struct RenderEngineType;
struct WorkSpace;
@@ -96,7 +97,8 @@ void DRW_draw_render_loop_offscreen(
struct RenderEngineType *engine_type,
struct ARegion *ar, struct View3D *v3d,
const bool draw_background,
struct GPUOffScreen *ofs);
struct GPUOffScreen *ofs,
struct GPUViewport *viewport);
void DRW_draw_select_loop(
struct Depsgraph *graph,
struct ARegion *ar, struct View3D *v3d,

View File

@@ -3523,9 +3523,11 @@ void DRW_draw_render_loop(
DRW_draw_render_loop_ex(graph, engine_type, ar, v3d, NULL);
}
/* @viewport CAN be NULL, in this case we create one. */
void DRW_draw_render_loop_offscreen(
struct Depsgraph *graph, RenderEngineType *engine_type,
ARegion *ar, View3D *v3d, const bool draw_background, GPUOffScreen *ofs)
ARegion *ar, View3D *v3d, const bool draw_background, GPUOffScreen *ofs,
GPUViewport *viewport)
{
RegionView3D *rv3d = ar->regiondata;
@@ -3533,7 +3535,12 @@ void DRW_draw_render_loop_offscreen(
void *backup_viewport = rv3d->viewport;
{
/* backup (_never_ use rv3d->viewport) */
rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
if (viewport == NULL) {
rv3d->viewport = GPU_viewport_create_from_offscreen(ofs);
}
else {
rv3d->viewport = viewport;
}
}
/* Reset before using it. */
@@ -3544,10 +3551,12 @@ void DRW_draw_render_loop_offscreen(
/* restore */
{
/* don't free data owned by 'ofs' */
GPU_viewport_clear_from_offscreen(rv3d->viewport);
GPU_viewport_free(rv3d->viewport);
MEM_freeN(rv3d->viewport);
if (viewport == NULL) {
/* don't free data owned by 'ofs' */
GPU_viewport_clear_from_offscreen(rv3d->viewport);
GPU_viewport_free(rv3d->viewport);
MEM_freeN(rv3d->viewport);
}
rv3d->viewport = backup_viewport;
}

View File

@@ -70,6 +70,7 @@ struct wmWindowManager;
struct GPUFX;
struct GPUOffScreen;
struct GPUFXSettings;
struct GPUViewport;
struct WorkSpace;
enum eGPUFXFlags;
@@ -380,7 +381,7 @@ void ED_view3d_draw_offscreen(
struct ViewLayer *view_layer, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
struct GPUFX *fx, struct GPUFXSettings *fx_settings,
struct GPUOffScreen *ofs);
struct GPUOffScreen *ofs, struct GPUViewport *viewport);
void ED_view3d_draw_setup_view(
struct wmWindow *win, const struct EvaluationContext *eval_ctx, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
float viewmat[4][4], float winmat[4][4], const struct rcti *rect);

View File

@@ -1966,7 +1966,7 @@ void ED_view3d_draw_offscreen(
float viewmat[4][4], float winmat[4][4],
bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
GPUFX *fx, GPUFXSettings *fx_settings,
GPUOffScreen *ofs)
GPUOffScreen *ofs, GPUViewport *viewport)
{
bool do_compositing = false;
RegionView3D *rv3d = ar->regiondata;
@@ -2060,7 +2060,7 @@ void ED_view3d_draw_offscreen(
/* XXX, should take depsgraph as arg */
Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
BLI_assert(depsgraph != NULL);
DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine_type, ar, v3d, do_sky, ofs);
DRW_draw_render_loop_offscreen(depsgraph, eval_ctx->engine_type, ar, v3d, do_sky, ofs, viewport);
}
/* restore size */
@@ -2159,7 +2159,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
ED_view3d_draw_offscreen(
eval_ctx, scene, view_layer, v3d, ar, sizex, sizey, NULL, winmat,
draw_background, draw_sky, !is_ortho, viewname,
fx, &fx_settings, ofs);
fx, &fx_settings, ofs, NULL);
if (ibuf->rect_float) {
GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
@@ -2175,6 +2175,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
float winmat_jitter[4][4];
float *rect_temp = (ibuf->rect_float) ? ibuf->rect_float : MEM_mallocN(sizex * sizey * sizeof(float[4]), "rect_temp");
float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float[4]), "accum_buffer");
GPUViewport *viewport = GPU_viewport_create_from_offscreen(ofs);
BLI_jitter_init(jit_ofs, samples);
@@ -2182,7 +2183,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
ED_view3d_draw_offscreen(
eval_ctx, scene, view_layer, v3d, ar, sizex, sizey, NULL, winmat,
draw_background, draw_sky, !is_ortho, viewname,
fx, &fx_settings, ofs);
fx, &fx_settings, ofs, viewport);
GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer);
/* skip the first sample */
@@ -2196,7 +2197,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
ED_view3d_draw_offscreen(
eval_ctx, scene, view_layer, v3d, ar, sizex, sizey, NULL, winmat_jitter,
draw_background, draw_sky, !is_ortho, viewname,
fx, &fx_settings, ofs);
fx, &fx_settings, ofs, viewport);
GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp);
unsigned int i = sizex * sizey * 4;
@@ -2205,6 +2206,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
}
}
{
/* don't free data owned by 'ofs' */
GPU_viewport_clear_from_offscreen(viewport);
GPU_viewport_free(viewport);
MEM_freeN(viewport);
}
if (ibuf->rect_float == NULL) {
MEM_freeN(rect_temp);
}

View File

@@ -1423,7 +1423,7 @@ static void gpu_update_lamps_shadows_world(const EvaluationContext *eval_ctx, Sc
ED_view3d_draw_offscreen(
eval_ctx, scene, eval_ctx->view_layer, v3d, &ar, winsize, winsize, viewmat, winmat,
false, false, true,
NULL, NULL, NULL, NULL);
NULL, NULL, NULL, NULL, NULL);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
v3d->drawtype = drawtype;