diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-04-25 21:39:25 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-04-25 21:59:18 +0300 |
commit | d8e83516e209cbb7c040211da558d7fff9ecc5be (patch) | |
tree | d332524c550188fb9034f3a7c182224427bea01d /source | |
parent | 041a50291b73b727fdf8bc3192de2917e8563ce0 (diff) |
Draw Manager: support for selection using engines
Needed to remove old draw code entirely.
Object mode selection support, pose and armature still need to be added.
Enabled when 'use_modern_viewport' is set.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/DRW_engine.h | 10 | ||||
-rw-r--r-- | source/blender/draw/engines/clay/clay.c | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 225 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 82 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_view.c | 16 | ||||
-rw-r--r-- | source/blender/gpu/GPU_viewport.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_viewport.c | 12 |
8 files changed, 299 insertions, 57 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index 60e8e40ea61..03ba8e39447 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -26,6 +26,7 @@ #ifndef __DRW_ENGINE_H__ #define __DRW_ENGINE_H__ +struct ARegion; struct CollectionEngineSettings; struct DRWPass; struct Material; @@ -34,6 +35,12 @@ struct DrawEngineType; struct IDProperty; struct bContext; struct Object; +struct SceneLayer; +struct ViewContext; +struct View3D; +struct rcti; + +#include "BLI_sys_types.h" /* for bool */ /* Buffer and textures used by the viewport by default */ typedef struct DefaultFramebufferList { @@ -54,6 +61,9 @@ void DRW_engine_viewport_data_size_get( int *r_fbl_len, int *r_txl_len, int *r_psl_len, int *r_stl_len); void DRW_draw_view(const struct bContext *C); +void DRW_draw_select_loop( + struct ViewContext *vc, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, + bool use_obedit_skip, bool use_nearest, const struct rcti *rect); void DRW_object_engine_data_free(struct Object *ob); diff --git a/source/blender/draw/engines/clay/clay.c b/source/blender/draw/engines/clay/clay.c index 5b1c6045808..3466f4f8b67 100644 --- a/source/blender/draw/engines/clay/clay.c +++ b/source/blender/draw/engines/clay/clay.c @@ -335,7 +335,7 @@ static void CLAY_engine_init(void *vedata) } } - { + if (DRW_viewport_is_fbo()) { const float *viewport_size = DRW_viewport_size_get(); DRWFboTexture tex = {&txl->depth_dup, DRW_BUF_DEPTH_24, 0}; DRW_framebuffer_init(&fbl->dupli_depth, @@ -607,7 +607,9 @@ static void CLAY_draw_scene(void *vedata) /* Pass 2 : Duplicate depth */ /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */ - DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true); + if (DRW_viewport_is_fbo()) { + DRW_framebuffer_blit(dfbl->default_fb, fbl->dupli_depth, true); + } /* Pass 3 : Shading */ DRW_draw_pass(psl->clay_pass); diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 93fd8d610ea..f98f39d7bb3 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -295,6 +295,8 @@ const float *DRW_viewport_size_get(void); const float *DRW_viewport_screenvecs_get(void); const float *DRW_viewport_pixelsize_get(void); bool DRW_viewport_is_persp_get(void); +bool DRW_viewport_is_fbo(void); +bool DRW_viewport_is_select(void); bool DRW_viewport_cache_is_dirty(void); struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 6046db874b8..67e2496e09f 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -77,6 +77,14 @@ #define MAX_ATTRIB_NAME 32 #define MAX_PASS_NAME 32 +/* Use draw manager to call GPU_select, see: DRW_draw_select_loop */ +#define USE_GPU_SELECT + +#ifdef USE_GPU_SELECT +# include "ED_view3d.h" +# include "GPU_select.h" +#endif + extern char datatoc_gpu_shader_2D_vert_glsl[]; extern char datatoc_gpu_shader_3D_vert_glsl[]; extern char datatoc_gpu_shader_fullscreen_vert_glsl[]; @@ -155,12 +163,18 @@ struct DRWPass { typedef struct DRWCall { struct DRWCall *next, *prev; +#ifdef USE_GPU_SELECT + int select_id; +#endif Batch *geometry; float (*obmat)[4]; } DRWCall; typedef struct DRWCallDynamic { struct DRWCallDynamic *next, *prev; +#ifdef USE_GPU_SELECT + int select_id; +#endif const void *data[]; } DRWCallDynamic; @@ -175,6 +189,11 @@ struct DRWShadingGroup { Batch *instance_geom; /* Geometry to instance */ Batch *batch_geom; /* Result of call batching */ + +#ifdef USE_GPU_SELECT + /* backlink to pass we're in */ + DRWPass *pass_parent; +#endif }; /* Used by DRWShadingGroup.type */ @@ -213,6 +232,15 @@ static struct DRWGlobalState { ListBase DRW_engines = {NULL, NULL}; +#ifdef USE_GPU_SELECT +static unsigned int g_DRW_select_id = (unsigned int)-1; + +static void DRW_select_id_set(unsigned int id) +{ + g_DRW_select_id = id; +} +#endif + /* ***************************************** TEXTURES ******************************************/ static void drw_texture_get_format(DRWTextureFormat format, GPUTextureFormat *data_type, int *channels) { @@ -457,6 +485,16 @@ static DRWInterface *DRW_interface_create(GPUShader *shader) return interface; } +#ifdef USE_GPU_SELECT +static DRWInterface *DRW_interface_duplicate(DRWInterface *interface_src) +{ + DRWInterface *interface_dst = MEM_dupallocN(interface_src); + BLI_duplicatelist(&interface_dst->uniforms, &interface_src->uniforms); + BLI_duplicatelist(&interface_dst->attribs, &interface_src->attribs); + return interface_dst; +} +#endif + static void DRW_interface_uniform(DRWShadingGroup *shgroup, const char *name, DRWUniformType type, const void *value, int length, int arraysize, int bindloc) { @@ -532,6 +570,10 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass) BLI_addtail(&pass->shgroups, shgroup); BLI_listbase_clear(&shgroup->calls); +#ifdef USE_GPU_SELECT + shgroup->pass_parent = pass; +#endif + return shgroup; } @@ -589,19 +631,40 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[ call->obmat = obmat; call->geometry = geom; +#ifdef USE_GPU_SELECT + call->select_id = g_DRW_select_id; +#endif + BLI_addtail(&shgroup->calls, call); } void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len) { DRWInterface *interface = shgroup->interface; + +#ifdef USE_GPU_SELECT + if ((G.f & G_PICKSEL) && (interface->instance_count > 0)) { + shgroup = MEM_dupallocN(shgroup); + BLI_listbase_clear(&shgroup->calls); + + shgroup->interface = interface = DRW_interface_duplicate(interface); + interface->instance_count = 0; + + BLI_addtail(&shgroup->pass_parent->shgroups, shgroup); + } +#endif + unsigned int data_size = sizeof(void *) * interface->attribs_count; - int size = sizeof(ListBase) + data_size; + int size = sizeof(DRWCallDynamic) + data_size; DRWCallDynamic *call = MEM_callocN(size, "DRWCallDynamic"); BLI_assert(attr_len == interface->attribs_count); +#ifdef USE_GPU_SELECT + call->select_id = g_DRW_select_id; +#endif + memcpy((void *)call->data, attr, data_size); interface->instance_count += 1; @@ -1097,6 +1160,9 @@ static void draw_shgroup(DRWShadingGroup *shgroup) GPU_shader_uniform_texture(shgroup->shader, uni->location, tex); break; case DRW_UNIFORM_BUFFER: + if (!DRW_viewport_is_fbo()) { + break; + } tex = *((GPUTexture **)uni->value); GPU_texture_bind(tex, uni->bindloc); GPU_texture_compare_mode(tex, false); @@ -1115,6 +1181,22 @@ static void draw_shgroup(DRWShadingGroup *shgroup) } } +#ifdef USE_GPU_SELECT + /* use the first item because of selection we only ever add one */ +# define GPU_SELECT_LOAD_IF_PICKSEL(_call) \ + if ((G.f & G_PICKSEL) && (_call)) { \ + GPU_select_load_id((_call)->select_id); \ + } ((void)0) +# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(_call_ls) \ + if ((G.f & G_PICKSEL) && (_call_ls)->first) { \ + BLI_assert(BLI_listbase_is_single(_call_ls)); \ + GPU_select_load_id(((DRWCall *)(_call_ls)->first)->select_id); \ + } ((void)0) +#else +# define GPU_SELECT_LOAD_IF_PICKSEL(call) +# define GPU_SELECT_LOAD_IF_PICKSEL_LIST(call) +#endif + /* Rendering Calls */ if (shgroup->type != DRW_SHG_NORMAL) { /* Replacing multiple calls with only one */ @@ -1122,17 +1204,20 @@ static void draw_shgroup(DRWShadingGroup *shgroup) unit_m4(obmat); if (shgroup->type == DRW_SHG_INSTANCE && interface->instance_count > 0) { + GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls); draw_geometry(shgroup, shgroup->instance_geom, obmat); } else { /* Some dynamic batch can have no geom (no call to aggregate) */ if (shgroup->batch_geom) { + GPU_SELECT_LOAD_IF_PICKSEL_LIST(&shgroup->calls); draw_geometry(shgroup, shgroup->batch_geom, obmat); } } } else { for (DRWCall *call = shgroup->calls.first; call; call = call->next) { + GPU_SELECT_LOAD_IF_PICKSEL(call); draw_geometry(shgroup, call->geometry, call->obmat); } } @@ -1410,22 +1495,26 @@ const float *DRW_viewport_pixelsize_get(void) * This is because a cache uniform only store reference * to its value. And we don't want to invalidate the cache * if this value change per viewport */ -static void DRW_viewport_var_init(const bContext *C) +static void DRW_viewport_var_init(void) { - /* Save context for all later needs */ - DRW_context_state_init(C, &DST.draw_ctx); - RegionView3D *rv3d = DST.draw_ctx.rv3d; /* Refresh DST.size */ - int size[2]; - GPU_viewport_size_get(DST.viewport, size); - DST.size[0] = size[0]; - DST.size[1] = size[1]; + if (DST.viewport) { + int size[2]; + GPU_viewport_size_get(DST.viewport, size); + DST.size[0] = size[0]; + DST.size[1] = size[1]; - DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport); - DST.default_framebuffer = fbl->default_fb; + DefaultFramebufferList *fbl = (DefaultFramebufferList *)GPU_viewport_framebuffer_list_get(DST.viewport); + DST.default_framebuffer = fbl->default_fb; + } + else { + DST.size[0] = 0; + DST.size[1] = 0; + DST.default_framebuffer = NULL; + } /* Refresh DST.screenvecs */ copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]); copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]); @@ -1456,6 +1545,23 @@ bool DRW_viewport_is_persp_get(void) return rv3d->is_persp; } +/** + * When false, drawing doesn't output to a pixel buffer + * eg: Occlusion queries, or when we have setup a context to draw in already. + */ +bool DRW_viewport_is_fbo(void) +{ + return (G.f & G_PICKSEL) == 0; +} + +/** + * For when engines need to know if this is drawing for selection or not. + */ +bool DRW_viewport_is_select(void) +{ + return (G.f & G_PICKSEL) != 0; +} + DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void) { return GPU_viewport_framebuffer_list_get(DST.viewport); @@ -1629,10 +1735,9 @@ static void use_drw_engine(DrawEngineType *engine) /* TODO revisit this when proper layering is implemented */ /* Gather all draw engines needed and store them in DST.enabled_engines * That also define the rendering order of engines */ -static void DRW_engines_enable(const bContext *C) +static void DRW_engines_enable_no_modes(const Scene *scene) { /* TODO layers */ - Scene *scene = CTX_data_scene(C); RenderEngineType *type = RE_engines_find(scene->r.engine); use_drw_engine(type->draw_engine); @@ -1640,6 +1745,12 @@ static void DRW_engines_enable(const bContext *C) * not on global state. * Order is important */ use_drw_engine(&draw_engine_object_type); +} + +static void DRW_engines_enable(const bContext *C) +{ + Scene *scene = CTX_data_scene(C); + DRW_engines_enable_no_modes(scene); switch (CTX_data_mode_enum(C)) { case CTX_MODE_EDIT_MESH: @@ -1858,7 +1969,10 @@ void DRW_draw_view(const bContext *C) /* Setup viewport */ cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash()); - DRW_viewport_var_init(C); + + /* Save context for all later needs */ + DRW_context_state_init(C, &DST.draw_ctx); + DRW_viewport_var_init(); /* Update ubos */ DRW_globals_update(); @@ -1909,6 +2023,89 @@ void DRW_draw_view(const bContext *C) memset(&DST, 0x0, sizeof(DST)); } +/** + * object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing). + */ +void DRW_draw_select_loop( + struct ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, + bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect) +{ +#ifndef USE_GPU_SELECT + UNUSED_VARS(vc, scene, sl, v3d, ar, rect); +#else + RegionView3D *rv3d = vc->rv3d; + + /* backup (_never_ use rv3d->viewport) */ + void *backup_viewport = vc->rv3d->viewport; + rv3d->viewport = NULL; + + struct GPUViewport *viewport = GPU_viewport_create(); + GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}); + + bool cache_is_dirty; + DST.viewport = viewport; + v3d->zbuf = true; + + /* Get list of enabled engines */ + DRW_engines_enable_no_modes(scene); + + /* Setup viewport */ + cache_is_dirty = true; + + /* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */ + DST.draw_ctx = (DRWContextState){ + ar, rv3d, v3d, scene, sl, (bContext *)NULL, + }; + + DRW_viewport_var_init(); + + /* Update ubos */ + DRW_globals_update(); + + /* Init engines */ + DRW_engines_init(); + + /* TODO : tag to refresh by the deps graph */ + /* ideally only refresh when objects are added/removed */ + /* or render properties / materials change */ + if (cache_is_dirty) { + int code = 1; + + DRW_engines_cache_init(); + + /* TODO, use DEG_OBJECT_ITER or similar. + * Currently its not well suited for selection + * since it loops over Objects instead of bases and does so recursively. */ + for (Base *base = sl->object_bases.first; base; base = base->next) { + base->selcol = code++; + DRW_select_id_set(base->selcol); + + DRW_engines_cache_populate(base->object); + } + + DRW_engines_cache_finish(); + } + + /* Start Drawing */ + DRW_draw_callbacks_pre_scene(); + DRW_engines_draw_scene(); + DRW_draw_callbacks_post_scene(); + + DRW_state_reset(); + DRW_engines_disable(); + + /* avoid accidental reuse */ + memset(&DST, 0x0, sizeof(DST)); + + /* Cleanup for selection state */ + GPU_viewport_free(viewport); + MEM_freeN(viewport); + + /* restore */ + rv3d->viewport = backup_viewport; +#endif /* USE_GPU_SELECT */ +} + /* ****************************************** OTHER ***************************************** */ void DRW_context_state_init(const bContext *C, DRWContextState *r_draw_ctx) diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 14478b377da..2bb0ec06383 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -219,16 +219,19 @@ static void OBJECT_engine_init(void *vedata) {&txl->outlines_depth_tx, DRW_BUF_DEPTH_24, 0}, {&txl->outlines_color_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER}, }; - DRW_framebuffer_init( - &fbl->outlines, - (int)viewport_size[0], (int)viewport_size[1], - tex, 2); - DRWFboTexture blur_tex = {&txl->outlines_blur_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER}; - DRW_framebuffer_init( - &fbl->blur, - (int)viewport_size[0], (int)viewport_size[1], - &blur_tex, 1); + if (DRW_viewport_is_fbo()) { + DRW_framebuffer_init( + &fbl->outlines, + (int)viewport_size[0], (int)viewport_size[1], + tex, 2); + + DRWFboTexture blur_tex = {&txl->outlines_blur_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER}; + DRW_framebuffer_init( + &fbl->blur, + (int)viewport_size[0], (int)viewport_size[1], + &blur_tex, 1); + } if (!e_data.outline_resolve_sh) { e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL); @@ -1268,50 +1271,55 @@ static void OBJECT_draw_scene(void *vedata) DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* Render filled polygon on a separate framebuffer */ - DRW_framebuffer_bind(fbl->outlines); - DRW_framebuffer_clear(true, true, false, clearcol, 1.0f); - DRW_draw_pass(psl->outlines); + if (!DRW_viewport_is_select()) { + /* Render filled polygon on a separate framebuffer */ + DRW_framebuffer_bind(fbl->outlines); + DRW_framebuffer_clear(true, true, false, clearcol, 1.0f); + DRW_draw_pass(psl->outlines); - /* detach textures */ - DRW_framebuffer_texture_detach(txl->outlines_depth_tx); + /* detach textures */ + DRW_framebuffer_texture_detach(txl->outlines_depth_tx); - /* Search outline pixels */ - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_search); + /* Search outline pixels */ + DRW_framebuffer_bind(fbl->blur); + DRW_draw_pass(psl->outlines_search); - /* Expand and fade gradually */ - DRW_framebuffer_bind(fbl->outlines); - DRW_draw_pass(psl->outlines_expand); + /* Expand and fade gradually */ + DRW_framebuffer_bind(fbl->outlines); + DRW_draw_pass(psl->outlines_expand); - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade1); + DRW_framebuffer_bind(fbl->blur); + DRW_draw_pass(psl->outlines_fade1); - DRW_framebuffer_bind(fbl->outlines); - DRW_draw_pass(psl->outlines_fade2); + DRW_framebuffer_bind(fbl->outlines); + DRW_draw_pass(psl->outlines_fade2); - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade3); + DRW_framebuffer_bind(fbl->blur); + DRW_draw_pass(psl->outlines_fade3); - DRW_framebuffer_bind(fbl->outlines); - DRW_draw_pass(psl->outlines_fade4); + DRW_framebuffer_bind(fbl->outlines); + DRW_draw_pass(psl->outlines_fade4); - DRW_framebuffer_bind(fbl->blur); - DRW_draw_pass(psl->outlines_fade5); + DRW_framebuffer_bind(fbl->blur); + DRW_draw_pass(psl->outlines_fade5); - /* reattach */ - DRW_framebuffer_texture_attach(fbl->outlines, txl->outlines_depth_tx, 0, 0); - DRW_framebuffer_bind(dfbl->default_fb); + /* reattach */ + DRW_framebuffer_texture_attach(fbl->outlines, txl->outlines_depth_tx, 0, 0); + DRW_framebuffer_bind(dfbl->default_fb); + } /* This needs to be drawn after the oultine */ DRW_draw_pass(psl->bone_wire); DRW_draw_pass(psl->bone_solid); DRW_draw_pass(psl->non_meshes); DRW_draw_pass(psl->ob_center); - DRW_draw_pass(psl->grid); - /* Combine with scene buffer last */ - DRW_draw_pass(psl->outlines_resolve); + if (!DRW_viewport_is_select()) { + DRW_draw_pass(psl->grid); + + /* Combine with scene buffer last */ + DRW_draw_pass(psl->outlines_resolve); + } } void OBJECT_collection_settings_create(IDProperty *props) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 4cfb30a9dd7..9fa616cee01 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -62,6 +62,8 @@ #include "ED_screen.h" #include "ED_armature.h" +#include "DRW_engine.h" + #ifdef WITH_GAMEENGINE # include "BLI_listbase.h" @@ -1180,7 +1182,12 @@ int view3d_opengl_select( GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0); - ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); + if (IS_VIEWPORT_LEGACY(vc->v3d)) { + ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); + } + else { + DRW_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest, &rect); + } hits = GPU_select_end(); @@ -1188,7 +1195,12 @@ int view3d_opengl_select( if (do_passes) { GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits); - ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); + if (IS_VIEWPORT_LEGACY(vc->v3d)) { + ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest); + } + else { + DRW_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest, &rect); + } GPU_select_end(); } diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 36e1eea5d61..f1a4e0bbcdb 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -89,7 +89,8 @@ void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type); void *GPU_viewport_engine_data_get(GPUViewport *viewport, void *engine_type); void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport); void *GPU_viewport_texture_list_get(GPUViewport *viewport); -void GPU_viewport_size_get(GPUViewport *viewport, int *size); +void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]); +void GPU_viewport_size_set(GPUViewport *viewport, const int size[2]); bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash); diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 162b7e2d87a..3781a9c8be0 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -151,12 +151,22 @@ void *GPU_viewport_texture_list_get(GPUViewport *viewport) return viewport->txl; } -void GPU_viewport_size_get(GPUViewport *viewport, int *size) +void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]) { size[0] = viewport->size[0]; size[1] = viewport->size[1]; } +/** + * Special case, this is needed for when we have a viewport without a frame-buffer output + * (occlusion queries for eg) but still need to set the size since it may be used for other calculations. + */ +void GPU_viewport_size_set(GPUViewport *viewport, const int size[2]) +{ + viewport->size[0] = size[0]; + viewport->size[1] = size[1]; +} + bool GPU_viewport_cache_validate(GPUViewport *viewport, unsigned int hash) { bool dirty = false; |