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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-04-27 11:22:37 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-04-27 13:14:14 +0300
commite01cadd657c76267266546781703df107c55f83a (patch)
treeaf6685123707af7cce17c74d681dcce378d4bc72 /source/blender/windowmanager/intern/wm_stereo.c
parent868c9ac408f75634c75bf4bc0b17c87b79d7af73 (diff)
WM: new offscreen window draw method to replace all existing methods.
For Blender 2.8 we had to be compatible with very old OpenGL versions, and triple buffer was designed to work without offscreen rendering, by copying the the backbuffer to a texture right before swapping. This way we could avoid redrawing unchanged regions by copying them from this texture on the next redraws. Triple buffer used to suffer from poor performance and driver bugs on specific cards, so alternative draw methods remained available. Now that we require newer OpenGL, we can have just a single draw method that draw each region into an offscreen buffer, and then draws those to the screen. This has some advantages: * Poor 3D view performance when using Region Overlap should be solved now, since we can also cache overlapping regions in offscreen buffers. * Page flip, anaglyph and interlace stereo drawing can be a little faster by avoiding a copy to an intermediate texture. * The new 3D view drawing already writes to an offscreen buffer, which we can draw from directly instead of duplicating it to another buffer. * Eventually we will be able to remove depth and stencil buffers from the window and save memory, though at the moment there are still some tools using it so it's not possible yet. * This also fixes a bug with Eevee sampling not progressing with stereo drawing in the 3D viewport. Differential Revision: https://developer.blender.org/D3061
Diffstat (limited to 'source/blender/windowmanager/intern/wm_stereo.c')
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c248
1 files changed, 81 insertions, 167 deletions
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index b52fc4ae213..14093d01695 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -53,35 +53,18 @@
#include "ED_screen.h"
#include "GPU_immediate.h"
+#include "GPU_framebuffer.h"
+#include "GPU_texture.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
-#include "wm_draw.h" /* wmDrawTriple */
+#include "wm_draw.h"
#include "wm_window.h"
#include "UI_interface.h"
#include "UI_resources.h"
-static void wm_method_draw_stereo3d_pageflip(wmWindow *win)
-{
- wmDrawData *drawdata;
- int view;
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
-
- if (view == STEREO_LEFT_ID)
- glDrawBuffer(GL_BACK_LEFT);
- else //STEREO_RIGHT_ID
- glDrawBuffer(GL_BACK_RIGHT);
-
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
- }
-
- glDrawBuffer(GL_BACK);
-}
-
static GPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType interlace_type)
{
switch (interlace_type) {
@@ -95,75 +78,60 @@ static GPUInterlaceShader interlace_gpu_id_from_type(eStereo3dInterlaceType inte
}
}
-static void wm_method_draw_stereo3d_interlace(wmWindow *win)
+void wm_stereo3d_draw_interlace(wmWindow *win, ARegion *ar)
{
bool swap = (win->stereo3d_format->flag & S3D_INTERLACE_SWAP) != 0;
enum eStereo3dInterlaceType interlace_type = win->stereo3d_format->interlace_type;
- wmDrawData *drawdata[2];
- for (int eye = 0; eye < 2; eye++) {
- int view = swap ? !eye : eye;
- drawdata[eye] = BLI_findlink(&win->drawdata, (view * 2) + 1);
- }
-
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
-
/* wmOrtho for the screen has this same offset */
- float ratiox = 1.0f;
- float ratioy = 1.0f;
- float halfx = GLA_PIXEL_OFS / sizex;
- float halfy = GLA_PIXEL_OFS / sizex;
+ float halfx = GLA_PIXEL_OFS / ar->winx;
+ float halfy = GLA_PIXEL_OFS / ar->winy;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_INTERLACE);
-
- /* leave GL_TEXTURE0 as the latest bind texture */
- for (int eye = 1; eye >= 0; eye--) {
- glActiveTexture(GL_TEXTURE0 + eye);
- glBindTexture(GL_TEXTURE_2D, drawdata[eye]->triple->bind);
+ /* leave GL_TEXTURE0 as the latest active texture */
+ for (int view = 1; view >= 0; view--) {
+ GPUTexture *texture = wm_draw_region_texture(ar, view);
+ glActiveTexture(GL_TEXTURE0 + view);
+ glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
}
- immUniform1i("image_a", 0);
- immUniform1i("image_b", 1);
+ 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(GWN_PRIM_TRI_FAN, 4);
immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, 0.0f, 0.0f);
+ immVertex2f(pos, ar->winrct.xmin, ar->winrct.ymin);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, sizex, 0.0f);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, ar->winrct.xmax + 1, ar->winrct.ymin);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, sizex, sizey);
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, ar->winrct.xmax + 1, ar->winrct.ymax + 1);
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, 0.0f, sizey);
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, ar->winrct.xmin, ar->winrct.ymax + 1);
immEnd();
immUnbindProgram();
- for (int eye = 1; eye >= 0; eye--) {
- glActiveTexture(GL_TEXTURE0 + eye);
+ for (int view = 1; view >= 0; view--) {
+ glActiveTexture(GL_TEXTURE0 + view);
glBindTexture(GL_TEXTURE_2D, 0);
}
}
-static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
+void wm_stereo3d_draw_anaglyph(wmWindow *win, ARegion *ar)
{
- wmDrawData *drawdata;
- int view, bit;
+ for (int view = 0; view < 2; view ++) {
+ int bit = view + 1;
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
-
- bit = view + 1;
switch (win->stereo3d_format->anaglyph_type) {
case S3D_ANAGLYPH_REDCYAN:
glColorMask((1&bit) ? GL_TRUE : GL_FALSE,
@@ -185,158 +153,104 @@ static void wm_method_draw_stereo3d_anaglyph(wmWindow *win)
break;
}
- wm_triple_draw_textures(win, drawdata->triple, 1.0f);
-
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ wm_draw_region_blend(ar, view, false);
}
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
-static void wm_method_draw_stereo3d_sidebyside(wmWindow *win)
+void wm_stereo3d_draw_sidebyside(wmWindow *win, int view)
{
- wmDrawData *drawdata;
- wmDrawTriple *triple;
- int view;
- int soffx;
bool cross_eyed = (win->stereo3d_format->flag & S3D_SIDEBYSIDE_CROSSEYED) != 0;
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
- glActiveTexture(GL_TEXTURE0);
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
- triple = drawdata->triple;
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
- soffx = WM_window_pixels_x(win) * 0.5f;
- if (view == STEREO_LEFT_ID) {
- if (!cross_eyed)
- soffx = 0;
- }
- else { //RIGHT_LEFT_ID
- if (cross_eyed)
- soffx = 0;
- }
-
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
+ int soffx = WM_window_pixels_x(win) * 0.5f;
+ if (view == STEREO_LEFT_ID) {
+ if (!cross_eyed)
+ soffx = 0;
+ }
+ else { //RIGHT_LEFT_ID
+ if (cross_eyed)
+ soffx = 0;
+ }
- /* wmOrtho for the screen has this same offset */
- const float ratiox = 1.0f;
- const float ratioy = 1.0f;
- const float halfx = GLA_PIXEL_OFS / sizex;
- const float halfy = GLA_PIXEL_OFS / sizey;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizex;
- immUniform1f("alpha", 1.0f);
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+ immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
- immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, soffx, 0.0f);
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, soffx, 0.0f);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), 0.0f);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, soffx + (sizex * 0.5f), sizey);
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, soffx, sizey);
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, soffx, sizey);
- immEnd();
- }
+ immEnd();
- glBindTexture(GL_TEXTURE_2D, 0);
immUnbindProgram();
}
-static void wm_method_draw_stereo3d_topbottom(wmWindow *win)
+void wm_stereo3d_draw_topbottom(wmWindow *win, int view)
{
- wmDrawData *drawdata;
- wmDrawTriple *triple;
- int view;
- int soffy;
-
Gwn_VertFormat *format = immVertexFormat();
unsigned int texcoord = GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_ALPHA);
- glActiveTexture(GL_TEXTURE0);
-
- for (view = 0; view < 2; view ++) {
- drawdata = BLI_findlink(&win->drawdata, (view * 2) + 1);
- triple = drawdata->triple;
-
- if (view == STEREO_LEFT_ID) {
- soffy = WM_window_pixels_y(win) * 0.5f;
- }
- else { /* STEREO_RIGHT_ID */
- soffy = 0;
- }
+ immBindBuiltinProgram(GPU_SHADER_2D_IMAGE);
- const int sizex = WM_window_pixels_x(win);
- const int sizey = WM_window_pixels_y(win);
+ int soffy;
+ if (view == STEREO_LEFT_ID) {
+ soffy = WM_window_pixels_y(win) * 0.5f;
+ }
+ else { /* STEREO_RIGHT_ID */
+ soffy = 0;
+ }
- /* wmOrtho for the screen has this same offset */
- const float ratiox = 1.0f;
- const float ratioy = 1.0f;
- const float halfx = GLA_PIXEL_OFS / sizex;
- const float halfy = GLA_PIXEL_OFS / sizey;
+ const int sizex = WM_window_pixels_x(win);
+ const int sizey = WM_window_pixels_y(win);
- glBindTexture(GL_TEXTURE_2D, triple->bind);
+ /* wmOrtho for the screen has this same offset */
+ const float halfx = GLA_PIXEL_OFS / sizex;
+ const float halfy = GLA_PIXEL_OFS / sizex;
- immUniform1f("alpha", 1.0f);
- immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
+ immUniform1i("image", 0); /* texture is already bound to GL_TEXTURE0 unit */
- immBegin(GWN_PRIM_TRI_FAN, 4);
+ immBegin(GWN_PRIM_TRI_FAN, 4);
- immAttrib2f(texcoord, halfx, halfy);
- immVertex2f(pos, 0.0f, soffy);
+ immAttrib2f(texcoord, halfx, halfy);
+ immVertex2f(pos, 0.0f, soffy);
- immAttrib2f(texcoord, ratiox + halfx, halfy);
- immVertex2f(pos, sizex, soffy);
+ immAttrib2f(texcoord, 1.0f + halfx, halfy);
+ immVertex2f(pos, sizex, soffy);
- immAttrib2f(texcoord, ratiox + halfx, ratioy + halfy);
- immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
+ immAttrib2f(texcoord, 1.0f + halfx, 1.0f + halfy);
+ immVertex2f(pos, sizex, soffy + (sizey * 0.5f));
- immAttrib2f(texcoord, halfx, ratioy + halfy);
- immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
+ immAttrib2f(texcoord, halfx, 1.0f + halfy);
+ immVertex2f(pos, 0.0f, soffy + (sizey * 0.5f));
- immEnd();
- }
+ immEnd();
immUnbindProgram();
- glBindTexture(GL_TEXTURE_2D, 0);
}
-void wm_method_draw_stereo3d(const bContext *UNUSED(C), wmWindow *win)
-{
- switch (win->stereo3d_format->display_mode) {
- case S3D_DISPLAY_ANAGLYPH:
- wm_method_draw_stereo3d_anaglyph(win);
- break;
- case S3D_DISPLAY_INTERLACE:
- wm_method_draw_stereo3d_interlace(win);
- break;
- case S3D_DISPLAY_PAGEFLIP:
- wm_method_draw_stereo3d_pageflip(win);
- break;
- case S3D_DISPLAY_SIDEBYSIDE:
- wm_method_draw_stereo3d_sidebyside(win);
- break;
- case S3D_DISPLAY_TOPBOTTOM:
- wm_method_draw_stereo3d_topbottom(win);
- break;
- default:
- break;
- }
-}
static bool wm_stereo3d_quadbuffer_supported(void)
{