diff options
Diffstat (limited to 'source/blender')
19 files changed, 332 insertions, 257 deletions
diff --git a/source/blender/draw/DRW_engine_types.h b/source/blender/draw/DRW_engine_types.h index dd56f87182c..d31bab5a1b5 100644 --- a/source/blender/draw/DRW_engine_types.h +++ b/source/blender/draw/DRW_engine_types.h @@ -35,11 +35,14 @@ typedef struct DefaultFramebufferList { struct GPUFrameBuffer *color_only_fb; struct GPUFrameBuffer *depth_only_fb; struct GPUFrameBuffer *overlay_only_fb; + struct GPUFrameBuffer *stereo_comp_fb; } DefaultFramebufferList; typedef struct DefaultTextureList { struct GPUTexture *color; struct GPUTexture *color_overlay; + struct GPUTexture *color_stereo; + struct GPUTexture *color_overlay_stereo; struct GPUTexture *depth; struct GPUTexture *depth_in_front; } DefaultTextureList; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index df3a1e3da79..0c049e030b1 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1218,7 +1218,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) /* Separate update for each stereo view. */ for (int view = 0; view < 2; view++) { - GPUViewport *viewport = WM_draw_region_get_viewport(region, view); + GPUViewport *viewport = WM_draw_region_get_viewport(region); if (!viewport) { continue; } @@ -1232,6 +1232,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) drw_state_prepare_clean_for_draw(&DST); DST.viewport = viewport; + GPU_viewport_active_view_set(viewport, view); DST.draw_ctx = (DRWContextState){ .region = region, .rv3d = rv3d, @@ -1416,7 +1417,6 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DST.draw_ctx.evil_C = evil_C; DST.viewport = viewport; - /* Setup viewport */ DST.draw_ctx = (DRWContextState){ .region = region, @@ -2374,7 +2374,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons drw_context_state_init(); /* Setup viewport */ - DST.viewport = WM_draw_region_get_viewport(region, 0); + DST.viewport = WM_draw_region_get_viewport(region); drw_viewport_var_init(); /* Update ubos */ diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 42a8a746eef..1fff40ab73a 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -646,8 +646,7 @@ static void image_main_region_draw(const bContext *C, ARegion *region) * old context since we now use it for drawing the entire area. */ gpu_batch_presets_reset(); - GPUViewport *viewport = - region->draw_buffer->viewport[region->draw_buffer->stereo ? sima->iuser.multiview_eye : 0]; + GPUViewport *viewport = region->draw_buffer->viewport; DefaultFramebufferList *fbl = GPU_viewport_framebuffer_list_get(viewport); GPU_framebuffer_bind(fbl->default_fb); GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 78d053c36a7..75865bc50e1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -855,7 +855,7 @@ void ED_view3d_draw_depth(Depsgraph *depsgraph, ARegion *region, View3D *v3d, bo WM_draw_region_viewport_ensure(region, SPACE_VIEW3D); WM_draw_region_viewport_bind(region); - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); /* When Blender is starting, a click event can trigger a depth test while the viewport is not * yet available. */ if (viewport != NULL) { @@ -2216,7 +2216,7 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc) Object *obact_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact); if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE_DEPSGRAPH) != 0)) { - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); DRW_draw_depth_object(vc->region, vc->v3d, viewport, obact_eval); } @@ -2279,7 +2279,7 @@ void view3d_update_depths_rect(ARegion *region, ViewDepths *d, rcti *rect) } if (d->damaged) { - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); view3d_opengl_read_Z_pixels(viewport, rect, d->depths); glGetDoublev(GL_DEPTH_RANGE, d->depth_range); d->damaged = false; @@ -2308,7 +2308,7 @@ void ED_view3d_depth_update(ARegion *region) } if (d->damaged) { - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); rcti r = { .xmin = 0, .xmax = d->w, @@ -2355,7 +2355,7 @@ void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *r GPU_depth_test(true); - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); DRW_draw_depth_loop_gpencil(depsgraph, region, v3d, viewport); GPU_depth_test(false); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 8a900938d2a..cf1d449ad3b 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -172,6 +172,7 @@ data_to_c_simple(shaders/gpu_shader_2D_image_multi_rect_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_desaturate_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_overlays_merge_frag.glsl SRC) +data_to_c_simple(shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_shuffle_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_mask_uniform_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_modulate_alpha_frag.glsl SRC) @@ -180,7 +181,6 @@ data_to_c_simple(shaders/gpu_shader_image_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_varying_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_depth_linear_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_depth_copy_frag.glsl SRC) -data_to_c_simple(shaders/gpu_shader_image_interlace_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_image_multisample_resolve_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_image_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_3D_vert.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index d5716cd1b31..334e295c636 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -184,6 +184,7 @@ typedef enum eGPUBuiltinShader { GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR, /* basic image drawing */ GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE, + GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE, GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR, GPU_SHADER_2D_IMAGE_MASK_UNIFORM_COLOR, /** @@ -207,8 +208,6 @@ typedef enum eGPUBuiltinShader { */ GPU_SHADER_3D_IMAGE_DEPTH, GPU_SHADER_3D_IMAGE_DEPTH_COPY, - /* stereo 3d */ - GPU_SHADER_2D_IMAGE_INTERLACE, /* points */ /** * Draw round points with a hardcoded size. @@ -353,17 +352,6 @@ typedef struct GPUShaderConfigData { /* gpu_shader.c */ extern const GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN]; -/** - * Keep these in sync with: - * - `gpu_shader_image_interlace_frag.glsl` - * - `gpu_shader_image_rect_interlace_frag.glsl` - */ -typedef enum eGPUInterlaceShader { - GPU_SHADER_INTERLACE_ROW = 0, - GPU_SHADER_INTERLACE_COLUMN = 1, - GPU_SHADER_INTERLACE_CHECKER = 2, -} eGPUInterlaceShader; - GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, eGPUShaderConfig sh_cfg); GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader); diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 848da778d1c..b7b8af9f90a 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -27,6 +27,7 @@ #include <stdbool.h> #include "DNA_vec_types.h" +#include "DNA_scene_types.h" #include "GPU_framebuffer.h" #include "GPU_texture.h" @@ -84,6 +85,8 @@ typedef struct ViewportEngineData { StorageList *stl; char info[GPU_INFO_SIZE]; + TextureList *txl_stereo; + StorageList *stl_stereo; /* we may want to put this elsewhere */ struct DRWTextStore *text_draw_cache; @@ -101,10 +104,12 @@ typedef struct ViewportEngineData_Info { } ViewportEngineData_Info; GPUViewport *GPU_viewport_create(void); -void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect); +GPUViewport *GPU_viewport_stereo_create(void); +void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect); void GPU_viewport_unbind(GPUViewport *viewport); -void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect); +void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect); void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, + int view, const rcti *rect, bool display_colorspace); void GPU_viewport_free(GPUViewport *viewport); @@ -125,9 +130,11 @@ struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *vie 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_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format); void *GPU_viewport_texture_list_get(GPUViewport *viewport); void GPU_viewport_size_get(const GPUViewport *viewport, int size[2]); void GPU_viewport_size_set(GPUViewport *viewport, const int size[2]); +void GPU_viewport_active_view_set(GPUViewport *viewport, int view); /* Profiling */ double *GPU_viewport_cache_time_get(GPUViewport *viewport); @@ -135,7 +142,7 @@ double *GPU_viewport_cache_time_get(GPUViewport *viewport); void GPU_viewport_tag_update(GPUViewport *viewport); bool GPU_viewport_do_update(GPUViewport *viewport); -GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport); +GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view); /* Texture pool */ GPUTexture *GPU_viewport_texture_pool_query( diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c index 6197d5f99b8..f254cce25e4 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.c +++ b/source/blender/gpu/intern/gpu_framebuffer.c @@ -943,6 +943,7 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save) glDisable(GL_SCISSOR_TEST); GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs); GPU_framebuffer_bind(ofs_fb); + glDisable(GL_FRAMEBUFFER_SRGB); } void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 0993d69e14d..620f18629b5 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -81,12 +81,12 @@ extern char datatoc_gpu_shader_2D_nodelink_vert_glsl[]; extern char datatoc_gpu_shader_3D_image_vert_glsl[]; extern char datatoc_gpu_shader_image_frag_glsl[]; extern char datatoc_gpu_shader_image_overlays_merge_frag_glsl[]; +extern char datatoc_gpu_shader_image_overlays_stereo_merge_frag_glsl[]; extern char datatoc_gpu_shader_image_color_frag_glsl[]; extern char datatoc_gpu_shader_image_desaturate_frag_glsl[]; extern char datatoc_gpu_shader_image_varying_color_frag_glsl[]; extern char datatoc_gpu_shader_image_alpha_color_frag_glsl[]; extern char datatoc_gpu_shader_image_shuffle_color_frag_glsl[]; -extern char datatoc_gpu_shader_image_interlace_frag_glsl[]; extern char datatoc_gpu_shader_image_mask_uniform_color_frag_glsl[]; extern char datatoc_gpu_shader_image_modulate_alpha_frag_glsl[]; extern char datatoc_gpu_shader_image_depth_linear_frag_glsl[]; @@ -975,11 +975,6 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { "#define USE_DEPTH\n", }, - [GPU_SHADER_2D_IMAGE_INTERLACE] = - { - .vert = datatoc_gpu_shader_2D_image_vert_glsl, - .frag = datatoc_gpu_shader_image_interlace_frag_glsl, - }, [GPU_SHADER_2D_CHECKER] = { .vert = datatoc_gpu_shader_2D_vert_glsl, @@ -1017,6 +1012,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = { .vert = datatoc_gpu_shader_2D_image_vert_glsl, .frag = datatoc_gpu_shader_image_overlays_merge_frag_glsl, }, + [GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE] = + { + .vert = datatoc_gpu_shader_2D_image_vert_glsl, + .frag = datatoc_gpu_shader_image_overlays_stereo_merge_frag_glsl, + }, [GPU_SHADER_2D_IMAGE] = { .vert = datatoc_gpu_shader_2D_image_vert_glsl, diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.c index 9ff518aec1b..6fd9b167599 100644 --- a/source/blender/gpu/intern/gpu_state.c +++ b/source/blender/gpu/intern/gpu_state.c @@ -218,6 +218,7 @@ typedef struct { uint is_sample_alpha_to_coverage : 1; uint is_scissor_test : 1; uint is_stencil_test : 1; + uint is_framebuffer_srgb : 1; bool is_clip_plane[6]; @@ -294,6 +295,7 @@ void gpuPushAttr(eGPUAttrMask mask) if ((mask & GPU_VIEWPORT_BIT) != 0) { glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far); glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport); + Attr.is_framebuffer_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB); } if ((mask & GPU_BLEND_BIT) != 0) { @@ -352,6 +354,7 @@ void gpuPopAttr(void) if ((mask & GPU_VIEWPORT_BIT) != 0) { glViewport(Attr.viewport[0], Attr.viewport[1], Attr.viewport[2], Attr.viewport[3]); glDepthRange(Attr.near_far[0], Attr.near_far[1]); + restore_mask(GL_FRAMEBUFFER_SRGB, Attr.is_framebuffer_srgb); } if ((mask & GPU_SCISSOR_BIT) != 0) { diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index e4fd5d3f122..750db39d908 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -40,6 +40,7 @@ #include "GPU_framebuffer.h" #include "GPU_glew.h" #include "GPU_immediate.h" +#include "GPU_matrix.h" #include "GPU_texture.h" #include "GPU_viewport.h" #include "GPU_uniformbuffer.h" @@ -68,7 +69,10 @@ struct GPUViewport { int size[2]; int flag; - /* If engine_handles mismatch we free all ViewportEngineData in this viewport */ + /* Set the active view (for stereoscoptic viewport rendering). */ + int active_view; + + /* If engine_handles mismatch we free all ViewportEngineData in this viewport. */ struct { void *handle; ViewportEngineData *data; @@ -80,9 +84,10 @@ struct GPUViewport { ViewportMemoryPool vmempool; /* Used for rendering data structure. */ struct DRWInstanceDataList *idatalist; /* Used for rendering data structure. */ - ListBase tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines */ + ListBase + tex_pool; /* ViewportTempTexture list : Temporary textures shared across draw engines. */ - /* Profiling data */ + /* Profiling data. */ double cache_time; /* Color management. */ @@ -96,12 +101,11 @@ struct GPUViewport { enum { DO_UPDATE = (1 << 0), + GPU_VIEWPORT_STEREO = (1 << 1), }; -static void gpu_viewport_buffers_free(FramebufferList *fbl, - int fbl_len, - TextureList *txl, - int txl_len); +static void gpu_viewport_buffers_free( + FramebufferList *fbl, int fbl_len, TextureList *txl, TextureList *txl_stereo, int txl_len); static void gpu_viewport_storage_free(StorageList *stl, int stl_len); static void gpu_viewport_passes_free(PassList *psl, int psl_len); static void gpu_viewport_texture_pool_free(GPUViewport *viewport); @@ -125,12 +129,89 @@ GPUViewport *GPU_viewport_create(void) viewport->txl = MEM_callocN(sizeof(DefaultTextureList), "TextureList"); viewport->idatalist = DRW_instance_data_list_create(); viewport->do_color_management = false; - viewport->size[0] = viewport->size[1] = -1; + viewport->active_view = -1; + return viewport; +} +GPUViewport *GPU_viewport_stereo_create(void) +{ + GPUViewport *viewport = GPU_viewport_create(); + viewport->flag = GPU_VIEWPORT_STEREO; return viewport; } +static void gpu_viewport_framebuffer_view_set(GPUViewport *viewport, int view) +{ + /* Early check if the view is the latest requested. */ + if (viewport->active_view == view) { + return; + } + DefaultFramebufferList *dfbl = viewport->fbl; + DefaultTextureList *dtxl = viewport->txl; + + /* Only swap the texture when this is a Stereo Viewport. */ + if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { + SWAP(GPUTexture *, dtxl->color, dtxl->color_stereo); + SWAP(GPUTexture *, dtxl->color_overlay, dtxl->color_overlay_stereo); + + for (int i = 0; i < MAX_ENABLE_ENGINE; i++) { + if (viewport->engine_data[i].handle != NULL) { + ViewportEngineData *data = viewport->engine_data[i].data; + SWAP(StorageList *, data->stl, data->stl_stereo); + SWAP(TextureList *, data->txl, data->txl_stereo); + } + else { + break; + } + } + } + + GPU_framebuffer_ensure_config(&dfbl->default_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_TEXTURE(dtxl->color), + }); + + GPU_framebuffer_ensure_config(&dfbl->overlay_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), + }); + + GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, + { + GPU_ATTACHMENT_TEXTURE(dtxl->depth), + GPU_ATTACHMENT_NONE, + }); + + GPU_framebuffer_ensure_config(&dfbl->color_only_fb, + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color), + }); + + GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb, + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), + }); + + if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { + GPU_framebuffer_ensure_config(&dfbl->stereo_comp_fb, + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(dtxl->color), + GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), + }); + } + else { + dfbl->stereo_comp_fb = NULL; + } + + viewport->active_view = view; +} + void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) { ViewportEngineData *data = MEM_callocN(sizeof(ViewportEngineData), "ViewportEngineData"); @@ -145,6 +226,13 @@ void *GPU_viewport_engine_data_create(GPUViewport *viewport, void *engine_type) data->psl = MEM_callocN((sizeof(void *) * psl_len) + sizeof(PassList), "PassList"); data->stl = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), "StorageList"); + if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0) { + data->txl_stereo = MEM_callocN((sizeof(void *) * txl_len) + sizeof(TextureList), + "TextureList"); + data->stl_stereo = MEM_callocN((sizeof(void *) * stl_len) + sizeof(StorageList), + "StorageList"); + } + for (int i = 0; i < MAX_ENABLE_ENGINE; i++) { if (viewport->engine_data[i].handle == NULL) { viewport->engine_data[i].handle = engine_type; @@ -166,7 +254,7 @@ static void gpu_viewport_engines_data_free(GPUViewport *viewport) DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, &psl_len, &stl_len); - gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len); + gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, data->txl_stereo, txl_len); gpu_viewport_passes_free(data->psl, psl_len); gpu_viewport_storage_free(data->stl, stl_len); @@ -175,6 +263,11 @@ static void gpu_viewport_engines_data_free(GPUViewport *viewport) MEM_freeN(data->psl); MEM_freeN(data->stl); + if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0) { + gpu_viewport_storage_free(data->stl_stereo, stl_len); + MEM_freeN(data->txl_stereo); + MEM_freeN(data->stl_stereo); + } /* We could handle this in the DRW module */ if (data->text_draw_cache) { extern void DRW_text_cache_destroy(struct DRWTextStore * dt); @@ -213,6 +306,16 @@ struct DRWInstanceDataList *GPU_viewport_instance_data_list_get(GPUViewport *vie return viewport->idatalist; } +/* Note this function is only allowed to be called from `DRW_notify_view_update`. The rest + * should bind the correct viewport. + * + * The reason is that DRW_notify_view_update can be called from a different thread, but needs + * access to the engine data. */ +void GPU_viewport_active_view_set(GPUViewport *viewport, int view) +{ + gpu_viewport_framebuffer_view_set(viewport, view); +} + void *GPU_viewport_framebuffer_list_get(GPUViewport *viewport) { return viewport->fbl; @@ -347,6 +450,10 @@ static void gpu_viewport_default_fb_create(GPUViewport *viewport) dtxl->color = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); dtxl->color_overlay = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); + if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { + dtxl->color_stereo = GPU_texture_create_2d(size[0], size[1], GPU_RGBA16F, NULL, NULL); + dtxl->color_overlay_stereo = GPU_texture_create_2d(size[0], size[1], GPU_SRGB8_A8, NULL, NULL); + } /* Can be shared with GPUOffscreen. */ if (dtxl->depth == NULL) { @@ -358,42 +465,16 @@ static void gpu_viewport_default_fb_create(GPUViewport *viewport) goto cleanup; } - GPU_framebuffer_ensure_config(&dfbl->default_fb, - { - GPU_ATTACHMENT_TEXTURE(dtxl->depth), - GPU_ATTACHMENT_TEXTURE(dtxl->color), - }); - - GPU_framebuffer_ensure_config(&dfbl->overlay_fb, - { - GPU_ATTACHMENT_TEXTURE(dtxl->depth), - GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), - }); - - GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, - { - GPU_ATTACHMENT_TEXTURE(dtxl->depth), - GPU_ATTACHMENT_NONE, - }); - - GPU_framebuffer_ensure_config(&dfbl->color_only_fb, - { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(dtxl->color), - }); - - GPU_framebuffer_ensure_config(&dfbl->overlay_only_fb, - { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(dtxl->color_overlay), - }); + gpu_viewport_framebuffer_view_set(viewport, 0); ok = ok && GPU_framebuffer_check_valid(dfbl->default_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->color_only_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->depth_only_fb, NULL); ok = ok && GPU_framebuffer_check_valid(dfbl->overlay_only_fb, NULL); - + if (((viewport->flag & GPU_VIEWPORT_STEREO) != 0)) { + ok = ok && GPU_framebuffer_check_valid(dfbl->stereo_comp_fb, NULL); + } cleanup: if (!ok) { GPU_viewport_free(viewport); @@ -404,7 +485,7 @@ cleanup: GPU_framebuffer_restore(); } -void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) +void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect) { DefaultFramebufferList *dfbl = viewport->fbl; int fbl_len, txl_len; @@ -421,15 +502,17 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, default_fbl_len, (TextureList *)viewport->txl, + NULL, default_txl_len); for (int i = 0; i < MAX_ENABLE_ENGINE && viewport->engine_data[i].handle; i++) { ViewportEngineData *data = viewport->engine_data[i].data; DRW_engine_viewport_data_size_get(data->engine_type, &fbl_len, &txl_len, NULL, NULL); - gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, txl_len); + gpu_viewport_buffers_free(data->fbl, fbl_len, data->txl, data->txl_stereo, txl_len); } gpu_viewport_texture_pool_free(viewport); + viewport->active_view = -1; } } @@ -440,6 +523,7 @@ void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect) if (!dfbl->default_fb) { gpu_viewport_default_fb_create(viewport); } + gpu_viewport_framebuffer_view_set(viewport, view); } void GPU_viewport_bind_from_offscreen(GPUViewport *viewport, struct GPUOffScreen *ofs) @@ -474,6 +558,74 @@ void GPU_viewport_colorspace_set(GPUViewport *viewport, viewport->do_color_management = true; } +/* Merge the stereo textures. `color` and `overlay` texture will be modified. */ +void GPU_viewport_stereo_composite(GPUViewport *viewport, Stereo3dFormat *stereo_format) +{ + if (!ELEM(stereo_format->display_mode, S3D_DISPLAY_ANAGLYPH, S3D_DISPLAY_INTERLACE)) { + /* Early Exit: the other display modes need access to the full screen and cannot be + * done from a single viewport. See `wm_stereo.c` */ + return; + } + gpu_viewport_framebuffer_view_set(viewport, 0); + DefaultTextureList *dtxl = viewport->txl; + DefaultFramebufferList *dfbl = viewport->fbl; + + GPUVertFormat *vert_format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_framebuffer_bind(dfbl->stereo_comp_fb); + GPU_matrix_push(); + GPU_matrix_push_projection(); + GPU_matrix_identity_set(); + GPU_matrix_identity_projection_set(); + immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE); + immUniform1i("imageTexture", 0); + immUniform1i("overlayTexture", 1); + int settings = stereo_format->display_mode; + if (settings == S3D_DISPLAY_ANAGLYPH) { + switch (stereo_format->anaglyph_type) { + case S3D_ANAGLYPH_REDCYAN: + glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + case S3D_ANAGLYPH_GREENMAGENTA: + glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE); + break; + case S3D_ANAGLYPH_YELLOWBLUE: + glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE); + break; + } + } + else if (settings == S3D_DISPLAY_INTERLACE) { + settings |= stereo_format->interlace_type << 3; + SET_FLAG_FROM_TEST(settings, stereo_format->flag & S3D_INTERLACE_SWAP, 1 << 6); + } + immUniform1i("stereoDisplaySettings", settings); + + GPU_texture_bind(dtxl->color_stereo, 0); + GPU_texture_bind(dtxl->color_overlay_stereo, 1); + + immBegin(GPU_PRIM_TRI_STRIP, 4); + + immVertex2f(pos, -1.0f, -1.0f); + immVertex2f(pos, 1.0f, -1.0f); + immVertex2f(pos, -1.0f, 1.0f); + immVertex2f(pos, 1.0f, 1.0f); + + immEnd(); + + GPU_texture_unbind(dtxl->color_stereo); + GPU_texture_unbind(dtxl->color_overlay_stereo); + + immUnbindProgram(); + GPU_matrix_pop_projection(); + GPU_matrix_pop(); + + if (settings == S3D_DISPLAY_ANAGLYPH) { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + + GPU_framebuffer_restore(); +} + static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, const rctf *rect_pos, const rctf *rect_uv, @@ -537,9 +689,11 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport, * transform should be performed. */ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, + int view, const rcti *rect, bool display_colorspace) { + gpu_viewport_framebuffer_view_set(viewport, view); DefaultFramebufferList *dfbl = viewport->fbl; DefaultTextureList *dtxl = viewport->txl; GPUTexture *color = dtxl->color; @@ -594,9 +748,9 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport, * \param rect: Coordinates to draw into. By swapping min and max values, drawing can be done with * inversed axis coordinates (upside down or sideways). */ -void GPU_viewport_draw_to_screen(GPUViewport *viewport, const rcti *rect) +void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect) { - GPU_viewport_draw_to_screen_ex(viewport, rect, true); + GPU_viewport_draw_to_screen_ex(viewport, view, rect, true); } /** @@ -642,22 +796,25 @@ void GPU_viewport_unbind(GPUViewport *UNUSED(viewport)) DRW_opengl_context_disable(); } -GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport) +GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view) { DefaultFramebufferList *dfbl = viewport->fbl; if (dfbl->default_fb) { DefaultTextureList *dtxl = viewport->txl; - return dtxl->color; + if (viewport->active_view == view) { + return dtxl->color; + } + else { + return dtxl->color_stereo; + } } return NULL; } -static void gpu_viewport_buffers_free(FramebufferList *fbl, - int fbl_len, - TextureList *txl, - int txl_len) +static void gpu_viewport_buffers_free( + FramebufferList *fbl, int fbl_len, TextureList *txl, TextureList *txl_stereo, int txl_len) { for (int i = 0; i < fbl_len; i++) { GPUFrameBuffer *fb = fbl->framebuffers[i]; @@ -673,6 +830,15 @@ static void gpu_viewport_buffers_free(FramebufferList *fbl, txl->textures[i] = NULL; } } + if (txl_stereo != NULL) { + for (int i = 0; i < txl_len; i++) { + GPUTexture *tex = txl_stereo->textures[i]; + if (tex) { + GPU_texture_free(tex); + txl_stereo->textures[i] = NULL; + } + } + } } static void gpu_viewport_storage_free(StorageList *stl, int stl_len) @@ -699,6 +865,7 @@ void GPU_viewport_free(GPUViewport *viewport) gpu_viewport_buffers_free((FramebufferList *)viewport->fbl, default_fbl_len, (TextureList *)viewport->txl, + NULL, default_txl_len); gpu_viewport_texture_pool_free(viewport); diff --git a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl deleted file mode 100644 index 9b9d8149e09..00000000000 --- a/source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl +++ /dev/null @@ -1,35 +0,0 @@ - -/* Keep these in sync with GPU_shader.h */ -#define INTERLACE_ROW 0 -#define INTERLACE_COLUMN 1 -#define INTERLACE_CHECKERBOARD 2 - -in vec2 texCoord_interp; -out vec4 fragColor; - -uniform int interlace_id; -uniform sampler2D image_a; -uniform sampler2D image_b; - -bool interlace() -{ - if (interlace_id == INTERLACE_CHECKERBOARD) { - return (int(gl_FragCoord.x + gl_FragCoord.y) & 1) != 0; - } - else if (interlace_id == INTERLACE_ROW) { - return (int(gl_FragCoord.y) & 1) != 0; - } - else if (interlace_id == INTERLACE_COLUMN) { - return (int(gl_FragCoord.x) & 1) != 0; - } -} - -void main() -{ - if (interlace()) { - fragColor = texture(image_a, texCoord_interp); - } - else { - fragColor = texture(image_b, texCoord_interp); - } -} diff --git a/source/blender/gpu/shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl b/source/blender/gpu/shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl new file mode 100644 index 00000000000..c6e9860d940 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl @@ -0,0 +1,47 @@ +#define S3D_DISPLAY_ANAGLYPH 0 +#define S3D_DISPLAY_INTERLACE 1 + +#define S3D_INTERLACE_ROW 0 +#define S3D_INTERLACE_COLUMN 1 +#define S3D_INTERLACE_CHECKERBOARD 2 + +/* Composite stereo textures */ + +uniform sampler2D imageTexture; +uniform sampler2D overlayTexture; + +uniform int stereoDisplaySettings; + +#define stereo_display_mode (stereoDisplaySettings & ((1 << 3) - 1)) +#define stereo_interlace_mode ((stereoDisplaySettings >> 3) & ((1 << 3) - 1)) +#define stereo_interlace_swap bool(stereoDisplaySettings >> 6) + +layout(location = 0) out vec4 imageColor; +layout(location = 1) out vec4 overlayColor; + +bool interlace(ivec2 texel) +{ + int interlace_mode = stereo_interlace_mode; + if (interlace_mode == S3D_INTERLACE_CHECKERBOARD) { + return ((texel.x + texel.y) & 1) != 0; + } + else if (interlace_mode == S3D_INTERLACE_ROW) { + return (texel.y & 1) != 0; + } + else if (interlace_mode == S3D_INTERLACE_COLUMN) { + return (texel.x & 1) != 0; + } +} + +void main() +{ + ivec2 texel = ivec2(gl_FragCoord.xy); + + if (stereo_display_mode == S3D_DISPLAY_INTERLACE && + (interlace(texel) == stereo_interlace_swap)) { + discard; + } + + imageColor = texelFetch(imageTexture, texel, 0); + overlayColor = texelFetch(overlayTexture, texel, 0); +} diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 1be7a8679c4..7426d64c769 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -778,7 +778,7 @@ void WM_draw_region_viewport_unbind(struct ARegion *region); /* Region drawing */ void WM_draw_region_free(struct ARegion *region); -struct GPUViewport *WM_draw_region_get_viewport(struct ARegion *region, int view); +struct GPUViewport *WM_draw_region_get_viewport(struct ARegion *region); struct GPUViewport *WM_draw_region_get_bound_viewport(struct ARegion *region); void WM_main_playanim(int argc, const char **argv); diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 5289b747f05..38cd667c422 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -235,7 +235,7 @@ static void wm_region_test_render_do_draw(const Scene *scene, if (sa->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; RenderEngine *engine = rv3d->render_engine; - GPUViewport *viewport = WM_draw_region_get_viewport(region, 0); + GPUViewport *viewport = WM_draw_region_get_viewport(region); if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) { View3D *v3d = sa->spacedata.first; @@ -332,10 +332,8 @@ static void wm_draw_callbacks(wmWindow *win) static void wm_draw_region_buffer_free(ARegion *region) { if (region->draw_buffer) { - for (int view = 0; view < 2; view++) { - if (region->draw_buffer->viewport[view]) { - GPU_viewport_free(region->draw_buffer->viewport[view]); - } + if (region->draw_buffer->viewport) { + GPU_viewport_free(region->draw_buffer->viewport); } if (region->draw_buffer->offscreen) { GPU_offscreen_free(region->draw_buffer->offscreen); @@ -361,7 +359,6 @@ static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen) /* GL_TEXTURE_BASE_LEVEL = 0 by default */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glBindTexture(GL_TEXTURE_2D, 0); } @@ -387,8 +384,8 @@ static void wm_draw_region_buffer_create(ARegion *region, bool stereo, bool use_ /* Allocate viewport which includes an offscreen buffer with depth * multisample, etc. */ region->draw_buffer = MEM_callocN(sizeof(wmDrawBuffer), "wmDrawBuffer"); - region->draw_buffer->viewport[0] = GPU_viewport_create(); - region->draw_buffer->viewport[1] = (stereo) ? GPU_viewport_create() : NULL; + region->draw_buffer->viewport = stereo ? GPU_viewport_stereo_create() : + GPU_viewport_create(); } else { /* Allocate offscreen buffer if it does not exist. This one has no @@ -417,8 +414,8 @@ static void wm_draw_region_bind(ARegion *region, int view) return; } - if (region->draw_buffer->viewport[view]) { - GPU_viewport_bind(region->draw_buffer->viewport[view], ®ion->winrct); + if (region->draw_buffer->viewport) { + GPU_viewport_bind(region->draw_buffer->viewport, view, ®ion->winrct); } else { GPU_offscreen_bind(region->draw_buffer->offscreen, false); @@ -432,7 +429,7 @@ static void wm_draw_region_bind(ARegion *region, int view) region->draw_buffer->bound_view = view; } -static void wm_draw_region_unbind(ARegion *region, int view) +static void wm_draw_region_unbind(ARegion *region) { if (!region->draw_buffer) { return; @@ -440,8 +437,8 @@ static void wm_draw_region_unbind(ARegion *region, int view) region->draw_buffer->bound_view = -1; - if (region->draw_buffer->viewport[view]) { - GPU_viewport_unbind(region->draw_buffer->viewport[view]); + if (region->draw_buffer->viewport) { + GPU_viewport_unbind(region->draw_buffer->viewport); } else { glDisable(GL_SCISSOR_TEST); @@ -460,14 +457,14 @@ static void wm_draw_region_blit(ARegion *region, int view) view = 0; } else if (view > 0) { - if (region->draw_buffer->viewport[view] == NULL) { + if (region->draw_buffer->viewport == NULL) { /* Region does not need stereo or failed to allocate stereo buffers. */ view = 0; } } - if (region->draw_buffer->viewport[view]) { - GPU_viewport_draw_to_screen(region->draw_buffer->viewport[view], ®ion->winrct); + if (region->draw_buffer->viewport) { + GPU_viewport_draw_to_screen(region->draw_buffer->viewport, view, ®ion->winrct); } else { GPU_offscreen_draw_to_screen( @@ -481,8 +478,9 @@ GPUTexture *wm_draw_region_texture(ARegion *region, int view) return NULL; } - if (region->draw_buffer->viewport[view]) { - return GPU_viewport_color_texture(region->draw_buffer->viewport[view]); + GPUViewport *viewport = region->draw_buffer->viewport; + if (viewport) { + return GPU_viewport_color_texture(viewport, view); } else { return GPU_offscreen_color_texture(region->draw_buffer->offscreen); @@ -573,13 +571,14 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend) } } -GPUViewport *WM_draw_region_get_viewport(ARegion *region, int view) +GPUViewport *WM_draw_region_get_viewport(ARegion *region) { if (!region->draw_buffer) { return NULL; } - return region->draw_buffer->viewport[view]; + GPUViewport *viewport = region->draw_buffer->viewport; + return viewport; } GPUViewport *WM_draw_region_get_bound_viewport(ARegion *region) @@ -588,8 +587,8 @@ GPUViewport *WM_draw_region_get_bound_viewport(ARegion *region) return NULL; } - int view = region->draw_buffer->bound_view; - return region->draw_buffer->viewport[view]; + GPUViewport *viewport = region->draw_buffer->viewport; + return viewport; } static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) @@ -650,14 +649,18 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) wm_draw_region_bind(region, view); ED_region_do_draw(C, region); - wm_draw_region_unbind(region, view); + wm_draw_region_unbind(region); + } + if (use_viewport) { + GPUViewport *viewport = region->draw_buffer->viewport; + GPU_viewport_stereo_composite(viewport, win->stereo3d_format); } } else { wm_draw_region_buffer_create(region, false, use_viewport); wm_draw_region_bind(region, 0); ED_region_do_draw(C, region); - wm_draw_region_unbind(region, 0); + wm_draw_region_unbind(region); } region->do_draw = false; @@ -686,7 +689,7 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); ED_region_do_draw(C, region); - wm_draw_region_unbind(region, 0); + wm_draw_region_unbind(region); region->do_draw = false; CTX_wm_menu_set(C, NULL); @@ -715,19 +718,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view) { for (ARegion *region = sa->regionbase.first; region; region = region->next) { if (region->visible && region->overlap == false) { - if (view == -1 && region->draw_buffer && region->draw_buffer->stereo) { - /* Stereo drawing from textures. */ - if (win->stereo3d_format->display_mode == S3D_DISPLAY_ANAGLYPH) { - wm_stereo3d_draw_anaglyph(win, region); - } - else { - wm_stereo3d_draw_interlace(win, region); - } - } - else { - /* Blit from offscreen buffer. */ - wm_draw_region_blit(region, view); - } + /* Blit from offscreen buffer. */ + wm_draw_region_blit(region, view); } } } @@ -789,7 +781,6 @@ static void wm_draw_window(bContext *C, wmWindow *win) { bScreen *screen = WM_window_get_active_screen(win); bool stereo = WM_stereo3d_enabled(win, false); - /* Draw area regions into their own framebuffer. This way we can redraw * the areas that need it, and blit the rest from existing framebuffers. */ wm_draw_window_offscreen(C, win, stereo); @@ -1028,7 +1019,7 @@ void wm_draw_region_test(bContext *C, ScrArea *sa, ARegion *region) wm_draw_region_buffer_create(region, false, use_viewport); wm_draw_region_bind(region, 0); ED_region_do_draw(C, region); - wm_draw_region_unbind(region, 0); + wm_draw_region_unbind(region); region->do_draw = false; } @@ -1068,7 +1059,7 @@ void WM_draw_region_viewport_bind(ARegion *region) void WM_draw_region_viewport_unbind(ARegion *region) { - wm_draw_region_unbind(region, 0); + wm_draw_region_unbind(region); } /** \} */ diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c index c5f8fb71b60..8ae343d5eb5 100644 --- a/source/blender/windowmanager/intern/wm_stereo.c +++ b/source/blender/windowmanager/intern/wm_stereo.c @@ -53,100 +53,6 @@ #include "UI_interface.h" #include "UI_resources.h" -static eGPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType interlace_type) -{ - switch (interlace_type) { - case S3D_INTERLACE_ROW: - return GPU_SHADER_INTERLACE_ROW; - case S3D_INTERLACE_COLUMN: - return GPU_SHADER_INTERLACE_COLUMN; - case S3D_INTERLACE_CHECKERBOARD: - default: - return GPU_SHADER_INTERLACE_CHECKER; - } -} - -void wm_stereo3d_draw_interlace(wmWindow *win, ARegion *region) -{ - bool swap = (win->stereo3d_format->flag & S3D_INTERLACE_SWAP) != 0; - enum eStereo3dInterlaceType interlace_type = win->stereo3d_format->interlace_type; - - /* wmOrtho for the screen has this same offset */ - float halfx = GLA_PIXEL_OFS / region->winx; - float halfy = GLA_PIXEL_OFS / region->winy; - - GPUVertFormat *format = immVertexFormat(); - uint texcoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - /* leave GL_TEXTURE0 as the latest active texture */ - for (int view = 1; view >= 0; view--) { - GPUTexture *texture = wm_draw_region_texture(region, view); - glActiveTexture(GL_TEXTURE0 + view); - glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture)); - } - - immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_INTERLACE); - immUniform1i("image_a", (swap) ? 1 : 0); - immUniform1i("image_b", (swap) ? 0 : 1); - - immUniform1i("interlace_id", interlace_gpu_id_from_type(interlace_type)); - - immBegin(GPU_PRIM_TRI_FAN, 4); - - immAttr2f(texcoord, halfx, halfy); - immVertex2f(pos, region->winrct.xmin, region->winrct.ymin); - - immAttr2f(texcoord, 1.0f + halfx, halfy); - immVertex2f(pos, region->winrct.xmax + 1, region->winrct.ymin); - - immAttr2f(texcoord, 1.0f + halfx, 1.0f + halfy); - immVertex2f(pos, region->winrct.xmax + 1, region->winrct.ymax + 1); - - immAttr2f(texcoord, halfx, 1.0f + halfy); - immVertex2f(pos, region->winrct.xmin, region->winrct.ymax + 1); - - immEnd(); - immUnbindProgram(); - - for (int view = 1; view >= 0; view--) { - glActiveTexture(GL_TEXTURE0 + view); - glBindTexture(GL_TEXTURE_2D, 0); - } -} - -void wm_stereo3d_draw_anaglyph(wmWindow *win, ARegion *region) -{ - for (int view = 0; view < 2; view++) { - int bit = view + 1; - - switch (win->stereo3d_format->anaglyph_type) { - case S3D_ANAGLYPH_REDCYAN: - glColorMask((1 & bit) ? GL_TRUE : GL_FALSE, - (2 & bit) ? GL_TRUE : GL_FALSE, - (2 & bit) ? GL_TRUE : GL_FALSE, - GL_FALSE); - break; - case S3D_ANAGLYPH_GREENMAGENTA: - glColorMask((2 & bit) ? GL_TRUE : GL_FALSE, - (1 & bit) ? GL_TRUE : GL_FALSE, - (2 & bit) ? GL_TRUE : GL_FALSE, - GL_FALSE); - break; - case S3D_ANAGLYPH_YELLOWBLUE: - glColorMask((1 & bit) ? GL_TRUE : GL_FALSE, - (1 & bit) ? GL_TRUE : GL_FALSE, - (2 & bit) ? GL_TRUE : GL_FALSE, - GL_FALSE); - break; - } - - wm_draw_region_blend(region, view, false); - } - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -} - void wm_stereo3d_draw_sidebyside(wmWindow *win, int view) { bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0; diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c index 4c770834f14..ef6fa6d28f2 100644 --- a/source/blender/windowmanager/intern/wm_xr.c +++ b/source/blender/windowmanager/intern/wm_xr.c @@ -685,7 +685,7 @@ static void wm_xr_draw_viewport_buffers_to_active_framebuffer( if (is_upside_down) { SWAP(int, rect.ymin, rect.ymax); } - GPU_viewport_draw_to_screen_ex(surface_data->viewport, &rect, draw_view->expects_srgb_buffer); + GPU_viewport_draw_to_screen_ex(surface_data->viewport, 0, &rect, draw_view->expects_srgb_buffer); } /** diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index 22c01df5d3b..97403a0315a 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -82,8 +82,6 @@ void wm_autosave_location(char *filepath); void WM_OT_splash(wmOperatorType *ot); /* wm_stereo.c */ -void wm_stereo3d_draw_interlace(wmWindow *win, struct ARegion *region); -void wm_stereo3d_draw_anaglyph(wmWindow *win, struct ARegion *region); void wm_stereo3d_draw_sidebyside(wmWindow *win, int view); void wm_stereo3d_draw_topbottom(wmWindow *win, int view); diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h index 4ebf2c820cd..b19fdf97569 100644 --- a/source/blender/windowmanager/wm_draw.h +++ b/source/blender/windowmanager/wm_draw.h @@ -32,7 +32,7 @@ struct GPUViewport; typedef struct wmDrawBuffer { struct GPUOffScreen *offscreen; - struct GPUViewport *viewport[2]; + struct GPUViewport *viewport; bool stereo; int bound_view; } wmDrawBuffer; |