2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-01-01 15:53:38 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2008-01-01 15:53:38 +00:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-01-01 15:53:38 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup wm
|
2014-01-19 23:14:24 +11:00
|
|
|
*
|
2018-02-16 22:41:46 +01:00
|
|
|
* OpenGL utilities for setting up 2D viewport for window and regions.
|
2011-02-25 14:04:21 +00:00
|
|
|
*/
|
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
#include "BLI_math.h"
|
|
|
|
#include "BLI_rect.h"
|
2008-01-01 15:53:38 +00:00
|
|
|
|
|
|
|
#include "DNA_screen_types.h"
|
2018-02-16 22:41:46 +01:00
|
|
|
#include "DNA_windowmanager_types.h"
|
2008-01-01 15:53:38 +00:00
|
|
|
|
2017-03-21 17:49:21 -04:00
|
|
|
#include "GPU_matrix.h"
|
2019-09-20 12:44:29 +02:00
|
|
|
#include "GPU_viewport.h"
|
2017-03-21 17:49:21 -04:00
|
|
|
|
2008-01-01 15:53:38 +00:00
|
|
|
#include "WM_api.h"
|
2014-04-02 17:33:20 +11:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
void wmViewport(const rcti *winrct)
|
2014-04-02 17:33:20 +11:00
|
|
|
{
|
2018-02-16 22:41:46 +01:00
|
|
|
int width = BLI_rcti_size_x(winrct) + 1;
|
|
|
|
int height = BLI_rcti_size_y(winrct) + 1;
|
Various changes made in the process of working on the UI code:
* Added functions to generate Timer events. There was some unfinished code to
create one timer per window, this replaces that with a way to let operators
or other handlers add/remove their own timers as needed. This is currently
delivered as an event with the timer handle, perhaps this should be a notifier
instead? Also includes some fixes in ghost for timer events that were not
delivered in time, due to passing negative timeout.
* Added a Message event, which is a generic event that can be added by any
operator. This is used in the UI code to communicate the results of opened
blocks. Again, this may be better as a notifier.
* These two events should not be blocked as they are intended for a specific
operator or handler, so there were exceptions added for this, which is one
of the reasons they might work better as notifiers, but currently these
things can't listen to notifier yet.
* Added an option to events to indicate if the customdata should be freed or
not.
* Added a free() callback for area regions, and added a free function for
area regions in blenkernel since it was already there for screens and areas.
* Added ED_screen/area/region_exit functions to clean up things like operators
and handlers when they are closed.
* Added screen level regions, these will draw over areas boundaries, with the
last created region on top. These are useful for tooltips, menus, etc, and
are not saved to file. It's using the same ARegion struct as areas to avoid
code duplication, but perhaps that should be renamed then. Note that redraws
currently go correct, because only full window redraws are used, for partial
redraws without any frontbuffer drawing, the window manager needs to get
support for compositing subwindows.
* Minor changes in the subwindow code to retrieve the matrix, and moved
setlinestyle to glutil.c.
* Reversed argument order in WM_event_add/remove_keymap_handler to be consistent
with modal_handler.
* Operators can now block events but not necessarily cancel/finish.
* Modal operators are now stored in a list in the window/area/region they were
created in. This means for example that when a transform operator is invoked
from a region but registers a handler at the window level (since mouse motion
across areas should work), it will still get removed when the region is closed
while the operator is running.
2008-11-11 15:18:21 +00:00
|
|
|
|
2020-07-17 19:03:30 +02:00
|
|
|
GPU_viewport(winrct->xmin, winrct->ymin, width, height);
|
2020-07-17 19:13:43 +02:00
|
|
|
GPU_scissor(winrct->xmin, winrct->ymin, width, height);
|
Various changes made in the process of working on the UI code:
* Added functions to generate Timer events. There was some unfinished code to
create one timer per window, this replaces that with a way to let operators
or other handlers add/remove their own timers as needed. This is currently
delivered as an event with the timer handle, perhaps this should be a notifier
instead? Also includes some fixes in ghost for timer events that were not
delivered in time, due to passing negative timeout.
* Added a Message event, which is a generic event that can be added by any
operator. This is used in the UI code to communicate the results of opened
blocks. Again, this may be better as a notifier.
* These two events should not be blocked as they are intended for a specific
operator or handler, so there were exceptions added for this, which is one
of the reasons they might work better as notifiers, but currently these
things can't listen to notifier yet.
* Added an option to events to indicate if the customdata should be freed or
not.
* Added a free() callback for area regions, and added a free function for
area regions in blenkernel since it was already there for screens and areas.
* Added ED_screen/area/region_exit functions to clean up things like operators
and handlers when they are closed.
* Added screen level regions, these will draw over areas boundaries, with the
last created region on top. These are useful for tooltips, menus, etc, and
are not saved to file. It's using the same ARegion struct as areas to avoid
code duplication, but perhaps that should be renamed then. Note that redraws
currently go correct, because only full window redraws are used, for partial
redraws without any frontbuffer drawing, the window manager needs to get
support for compositing subwindows.
* Minor changes in the subwindow code to retrieve the matrix, and moved
setlinestyle to glutil.c.
* Reversed argument order in WM_event_add/remove_keymap_handler to be consistent
with modal_handler.
* Operators can now block events but not necessarily cancel/finish.
* Modal operators are now stored in a list in the window/area/region they were
created in. This means for example that when a transform operator is invoked
from a region but registers a handler at the window level (since mouse motion
across areas should work), it will still get removed when the region is closed
while the operator is running.
2008-11-11 15:18:21 +00:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
wmOrtho2_pixelspace(width, height);
|
2018-07-15 15:27:15 +02:00
|
|
|
GPU_matrix_identity_set();
|
Various changes made in the process of working on the UI code:
* Added functions to generate Timer events. There was some unfinished code to
create one timer per window, this replaces that with a way to let operators
or other handlers add/remove their own timers as needed. This is currently
delivered as an event with the timer handle, perhaps this should be a notifier
instead? Also includes some fixes in ghost for timer events that were not
delivered in time, due to passing negative timeout.
* Added a Message event, which is a generic event that can be added by any
operator. This is used in the UI code to communicate the results of opened
blocks. Again, this may be better as a notifier.
* These two events should not be blocked as they are intended for a specific
operator or handler, so there were exceptions added for this, which is one
of the reasons they might work better as notifiers, but currently these
things can't listen to notifier yet.
* Added an option to events to indicate if the customdata should be freed or
not.
* Added a free() callback for area regions, and added a free function for
area regions in blenkernel since it was already there for screens and areas.
* Added ED_screen/area/region_exit functions to clean up things like operators
and handlers when they are closed.
* Added screen level regions, these will draw over areas boundaries, with the
last created region on top. These are useful for tooltips, menus, etc, and
are not saved to file. It's using the same ARegion struct as areas to avoid
code duplication, but perhaps that should be renamed then. Note that redraws
currently go correct, because only full window redraws are used, for partial
redraws without any frontbuffer drawing, the window manager needs to get
support for compositing subwindows.
* Minor changes in the subwindow code to retrieve the matrix, and moved
setlinestyle to glutil.c.
* Reversed argument order in WM_event_add/remove_keymap_handler to be consistent
with modal_handler.
* Operators can now block events but not necessarily cancel/finish.
* Modal operators are now stored in a list in the window/area/region they were
created in. This means for example that when a transform operator is invoked
from a region but registers a handler at the window level (since mouse motion
across areas should work), it will still get removed when the region is closed
while the operator is running.
2008-11-11 15:18:21 +00:00
|
|
|
}
|
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct)
|
2014-04-02 17:33:20 +11:00
|
|
|
{
|
2018-02-16 22:41:46 +01:00
|
|
|
/* Setup part of the viewport for partial redraw. */
|
|
|
|
bool scissor_pad;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
if (partialrct->xmin == partialrct->xmax) {
|
|
|
|
/* Full region. */
|
|
|
|
*drawrct = *winrct;
|
|
|
|
scissor_pad = true;
|
2014-04-02 17:33:20 +11:00
|
|
|
}
|
|
|
|
else {
|
2018-02-16 22:41:46 +01:00
|
|
|
/* Partial redraw, clipped to region. */
|
|
|
|
BLI_rcti_isect(winrct, partialrct, drawrct);
|
|
|
|
scissor_pad = false;
|
2016-02-02 14:13:57 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-27 10:22:37 +02:00
|
|
|
int x = drawrct->xmin - winrct->xmin;
|
|
|
|
int y = drawrct->ymin - winrct->ymin;
|
2018-02-16 22:41:46 +01:00
|
|
|
int width = BLI_rcti_size_x(winrct) + 1;
|
|
|
|
int height = BLI_rcti_size_y(winrct) + 1;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
int scissor_width = BLI_rcti_size_x(drawrct);
|
|
|
|
int scissor_height = BLI_rcti_size_y(drawrct);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
/* Partial redraw rect uses different convention than region rect,
|
|
|
|
* so compensate for that here. One pixel offset is noticeable with
|
|
|
|
* viewport border render. */
|
|
|
|
if (scissor_pad) {
|
|
|
|
scissor_width += 1;
|
|
|
|
scissor_height += 1;
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-17 19:03:30 +02:00
|
|
|
GPU_viewport(0, 0, width, height);
|
2020-07-17 19:13:43 +02:00
|
|
|
GPU_scissor(x, y, scissor_width, scissor_height);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
wmOrtho2_pixelspace(width, height);
|
2018-07-15 15:27:15 +02:00
|
|
|
GPU_matrix_identity_set();
|
2008-01-01 15:53:38 +00:00
|
|
|
}
|
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
void wmWindowViewport(wmWindow *win)
|
2008-01-01 15:53:38 +00:00
|
|
|
{
|
2018-02-16 22:41:46 +01:00
|
|
|
int width = WM_window_pixels_x(win);
|
|
|
|
int height = WM_window_pixels_y(win);
|
2013-08-05 04:52:27 +00:00
|
|
|
|
2020-07-17 19:03:30 +02:00
|
|
|
GPU_viewport(0, 0, width, height);
|
2020-07-17 19:13:43 +02:00
|
|
|
GPU_scissor(0, 0, width, height);
|
2013-08-05 04:52:27 +00:00
|
|
|
|
2014-09-10 13:24:31 +10:00
|
|
|
wmOrtho2_pixelspace(width, height);
|
2018-07-15 15:27:15 +02:00
|
|
|
GPU_matrix_identity_set();
|
2.5: WM Compositing
* Triple Buffer is now more complete:
- Proper handling of window resize, duplicate, etc.
- It now uses 3x3 textures (or less) if the power of two sizes
do not match well. That still has a worst case wast of 23.4%,
but better than 300%.
- It can also use the ARB/NV/EXT_texture_rectangle extension
now, which may be supported on hardware that does not support
ARB_texture_non_power_of_two.
- Gesture, menu and brushe redraws now require no redraws at all
from the area regions. So even on a high poly scene just moving
the paint cursor or opening a menu should be fast.
* Testing can be done by setting the "Window Draw Method" in the
User Preferences in the outliner. "Overlap" is still default,
since "Triple Buffer" has not been tested on computers other than
mine, would like to avoid crashing Blender on startup in case
there is a common bug, but it's ready for testing now.
- For reference "Full" draws the full window each time.
- "Triple Buffer" should work for both swap copy and swap exchange
systems, the latter still need the -E command line option for
"Overlap".
- Resizing and going fullscreen still gives flicker here but no
more than "Full" drawing.
* Partial Redraw was added. ED_region_tag_redraw_partial takes a
rect in window coordinates to define a subarea of the region.
On region draw it will then set glScissor to a smaller area, and
ar->drawrct will always be set to either the partial or full
window rect. The latter can then be used for clipping in the 3D
view or clipping interface drawing. Neither is implemented yet.
2009-01-23 03:52:52 +00:00
|
|
|
}
|
|
|
|
|
2008-12-19 14:14:43 +00:00
|
|
|
void wmOrtho2(float x1, float x2, float y1, float y2)
|
2008-01-01 15:53:38 +00:00
|
|
|
{
|
|
|
|
/* prevent opengl from generating errors */
|
2019-04-13 09:15:15 +02:00
|
|
|
if (x2 == x1) {
|
|
|
|
x2 += 1.0f;
|
|
|
|
}
|
|
|
|
if (y2 == y1) {
|
|
|
|
y2 += 1.0f;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-04 22:17:01 +11:00
|
|
|
GPU_matrix_ortho_set(
|
|
|
|
x1, x2, y1, y2, GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT, GPU_MATRIX_ORTHO_CLIP_FAR_DEFAULT);
|
2009-12-17 19:55:08 +00:00
|
|
|
}
|
2008-01-01 15:53:38 +00:00
|
|
|
|
2014-09-10 13:24:31 +10:00
|
|
|
static void wmOrtho2_offset(const float x, const float y, const float ofs)
|
|
|
|
{
|
|
|
|
wmOrtho2(ofs, x + ofs, ofs, y + ofs);
|
|
|
|
}
|
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
/* Default pixel alignment for regions. */
|
2020-03-06 16:56:42 +01:00
|
|
|
void wmOrtho2_region_pixelspace(const ARegion *region)
|
2014-09-10 13:24:31 +10:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
wmOrtho2_offset(region->winx, region->winy, -0.01f);
|
2014-09-10 13:24:31 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
void wmOrtho2_pixelspace(const float x, const float y)
|
|
|
|
{
|
|
|
|
wmOrtho2_offset(x, y, -GLA_PIXEL_OFS);
|
|
|
|
}
|
|
|
|
|
2018-02-16 22:41:46 +01:00
|
|
|
void wmGetProjectionMatrix(float mat[4][4], const rcti *winrct)
|
|
|
|
{
|
|
|
|
int width = BLI_rcti_size_x(winrct) + 1;
|
|
|
|
int height = BLI_rcti_size_y(winrct) + 1;
|
|
|
|
orthographic_m4(mat,
|
|
|
|
-GLA_PIXEL_OFS,
|
|
|
|
(float)width - GLA_PIXEL_OFS,
|
|
|
|
-GLA_PIXEL_OFS,
|
|
|
|
(float)height - GLA_PIXEL_OFS,
|
2020-02-04 22:17:01 +11:00
|
|
|
GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT,
|
|
|
|
GPU_MATRIX_ORTHO_CLIP_FAR_DEFAULT);
|
2018-02-16 22:41:46 +01:00
|
|
|
}
|