Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/DRW_engine_types.h3
-rw-r--r--source/blender/draw/intern/draw_manager.c6
-rw-r--r--source/blender/editors/space_image/space_image.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c10
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_shader.h14
-rw-r--r--source/blender/gpu/GPU_viewport.h13
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c1
-rw-r--r--source/blender/gpu/intern/gpu_shader.c12
-rw-r--r--source/blender/gpu/intern/gpu_state.c3
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c265
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_interlace_frag.glsl35
-rw-r--r--source/blender/gpu/shaders/gpu_shader_image_overlays_stereo_merge_frag.glsl47
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c73
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c94
-rw-r--r--source/blender/windowmanager/intern/wm_xr.c2
-rw-r--r--source/blender/windowmanager/wm.h2
-rw-r--r--source/blender/windowmanager/wm_draw.h2
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], &region->winrct);
+ if (region->draw_buffer->viewport) {
+ GPU_viewport_bind(region->draw_buffer->viewport, view, &region->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], &region->winrct);
+ if (region->draw_buffer->viewport) {
+ GPU_viewport_draw_to_screen(region->draw_buffer->viewport, view, &region->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;