2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2008-01-07 18:03:41 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* 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-07 18:03:41 +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-07 18:03:41 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): Blender Foundation
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/screen/glutil.c
|
|
|
|
* \ingroup edscr
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
#include "DNA_userdef_types.h"
|
2008-01-07 18:03:41 +00:00
|
|
|
#include "DNA_vec_types.h"
|
|
|
|
|
2012-08-21 20:34:05 +00:00
|
|
|
#include "BLI_rect.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2013-01-24 21:57:13 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
|
2013-04-02 17:28:37 +00:00
|
|
|
#include "BKE_context.h"
|
2008-01-07 18:03:41 +00:00
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
#include "BIF_glutil.h"
|
|
|
|
|
2013-04-02 17:28:37 +00:00
|
|
|
#include "IMB_colormanagement.h"
|
|
|
|
#include "IMB_imbuf_types.h"
|
|
|
|
|
2016-08-20 15:40:08 -04:00
|
|
|
#include "GPU_immediate.h"
|
2017-03-21 16:08:14 -04:00
|
|
|
#include "GPU_matrix.h"
|
2018-06-27 19:07:23 -06:00
|
|
|
#include "GPU_state.h"
|
2015-11-28 01:20:28 +01:00
|
|
|
|
2014-06-05 20:05:41 +06:00
|
|
|
#include "UI_interface.h"
|
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
/* ******************************************** */
|
|
|
|
|
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
|
|
|
void setlinestyle(int nr)
|
|
|
|
{
|
2012-05-08 15:43:59 +00:00
|
|
|
if (nr == 0) {
|
2018-06-27 19:07:23 -06:00
|
|
|
GPU_line_stipple(false);
|
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
|
|
|
}
|
|
|
|
else {
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2018-06-27 19:07:23 -06:00
|
|
|
GPU_line_stipple(true);
|
Holiday coding log :)
Nice formatted version (pictures soon):
http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability
Short list of main changes:
- Transparent region option (over main region), added code to blend in/out such panels.
- Min size window now 640 x 480
- Fixed DPI for ui - lots of cleanup and changes everywhere. Icon image need correct size still, layer-in-use icon needs remake.
- Macbook retina support, use command line --no-native-pixels to disable it
- Timeline Marker label was drawing wrong
- Trackpad and magic mouse: supports zoom (hold ctrl)
- Fix for splash position: removed ghost function and made window size update after creation immediate
- Fast undo buffer save now adds UI as well. Could be checked for regular file save even...
Quit.blend and temp file saving use this now.
- Dixed filename in window on reading quit.blend or temp saves, and they now add a warning in window title: "(Recovered)"
- New Userpref option "Keep Session" - this always saves quit.blend, and loads on start.
This allows keeping UI and data without actual saves, until you actually save.
When you load startup.blend and quit, it recognises the quit.blend as a startup (no file name in header)
- Added 3D view copy/paste buffers (selected objects). Shortcuts ctrl-c, ctrl-v (OSX, cmd-c, cmd-v).
Coded partial file saving for it. Could be used for other purposes. Todo: use OS clipboards.
- User preferences (themes, keymaps, user settings) now can be saved as a separate file.
Old option is called "Save Startup File" the new one "Save User Settings".
To visualise this difference, the 'save startup file' button has been removed from user preferences window. That option is available as CTRL+U and in File menu still.
- OSX: fixed bug that stopped giving mouse events outside window.
This also fixes "Continuous Grab" for OSX. (error since 2009)
2012-12-12 18:58:11 +00:00
|
|
|
if (U.pixelsize > 1.0f)
|
|
|
|
glLineStipple(nr, 0xCCCC);
|
|
|
|
else
|
|
|
|
glLineStipple(nr, 0xAAAA);
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-08 15:43:59 +00:00
|
|
|
/* Invert line handling */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-09-06 01:31:15 +00:00
|
|
|
#define GL_TOGGLE(mode, onoff) (((onoff) ? glEnable : glDisable)(mode))
|
2008-01-07 18:03:41 +00:00
|
|
|
|
2018-06-04 09:31:30 +02:00
|
|
|
void set_inverted_drawing(int enable)
|
2008-01-07 18:03:41 +00:00
|
|
|
{
|
2012-05-08 15:43:59 +00:00
|
|
|
glLogicOp(enable ? GL_INVERT : GL_COPY);
|
2012-09-06 01:31:15 +00:00
|
|
|
GL_TOGGLE(GL_COLOR_LOGIC_OP, enable);
|
|
|
|
GL_TOGGLE(GL_DITHER, !enable);
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float glaGetOneFloat(int param)
|
|
|
|
{
|
|
|
|
GLfloat v;
|
|
|
|
glGetFloatv(param, &v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2016-06-09 05:12:42 +10:00
|
|
|
int glaGetOneInt(int param)
|
|
|
|
{
|
|
|
|
GLint v;
|
|
|
|
glGetIntegerv(param, &v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y)
|
|
|
|
{
|
2012-05-08 15:43:59 +00:00
|
|
|
GLubyte dummy = 0;
|
2008-01-07 18:03:41 +00:00
|
|
|
|
2012-05-08 15:43:59 +00:00
|
|
|
/* As long as known good coordinates are correct
|
|
|
|
* this is guaranteed to generate an ok raster
|
|
|
|
* position (ignoring potential (real) overflow
|
|
|
|
* issues).
|
|
|
|
*/
|
2008-01-07 18:03:41 +00:00
|
|
|
glRasterPos2f(known_good_x, known_good_y);
|
|
|
|
|
2012-05-08 15:43:59 +00:00
|
|
|
/* Now shift the raster position to where we wanted
|
|
|
|
* it in the first place using the glBitmap trick.
|
|
|
|
*/
|
2008-01-07 18:03:41 +00:00
|
|
|
glBitmap(0, 0, 0, 0, x - known_good_x, y - known_good_y, &dummy);
|
|
|
|
}
|
|
|
|
|
2014-03-16 03:24:05 +11:00
|
|
|
static int get_cached_work_texture(int *r_w, int *r_h)
|
2008-01-07 18:03:41 +00:00
|
|
|
{
|
2012-05-08 15:43:59 +00:00
|
|
|
static GLint texid = -1;
|
|
|
|
static int tex_w = 256;
|
|
|
|
static int tex_h = 256;
|
2008-01-07 18:03:41 +00:00
|
|
|
|
2012-05-08 15:43:59 +00:00
|
|
|
if (texid == -1) {
|
2008-01-07 18:03:41 +00:00
|
|
|
glGenTextures(1, (GLuint *)&texid);
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texid);
|
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
2015-12-26 22:23:12 -05:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
2008-01-07 18:03:41 +00:00
|
|
|
|
2015-11-28 01:45:23 +01:00
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
|
|
|
|
2014-03-16 03:24:05 +11:00
|
|
|
*r_w = tex_w;
|
|
|
|
*r_h = tex_h;
|
2008-01-07 18:03:41 +00:00
|
|
|
return texid;
|
|
|
|
}
|
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
static void immDrawPixelsTexSetupAttributes(IMMDrawPixelsTexState *state)
|
|
|
|
{
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertFormat *vert_format = immVertexFormat();
|
|
|
|
state->pos = GPU_vertformat_attr_add(vert_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
state->texco = GPU_vertformat_attr_add(vert_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2017-04-11 16:30:00 +02:00
|
|
|
}
|
|
|
|
|
2017-02-24 11:11:43 +01:00
|
|
|
/* To be used before calling immDrawPixelsTex
|
|
|
|
* Default shader is GPU_SHADER_2D_IMAGE_COLOR
|
|
|
|
* You can still set uniforms with :
|
|
|
|
* GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);
|
|
|
|
* */
|
2017-04-11 16:30:00 +02:00
|
|
|
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
|
2017-02-24 11:11:43 +01:00
|
|
|
{
|
2017-04-11 16:30:00 +02:00
|
|
|
IMMDrawPixelsTexState state;
|
|
|
|
immDrawPixelsTexSetupAttributes(&state);
|
|
|
|
|
2017-04-12 19:11:31 -04:00
|
|
|
state.shader = GPU_shader_get_builtin_shader(builtin);
|
|
|
|
|
2017-02-24 11:11:43 +01:00
|
|
|
/* Shader will be unbind by immUnbindProgram in immDrawPixelsTexScaled_clipping */
|
2017-04-11 16:30:00 +02:00
|
|
|
immBindBuiltinProgram(builtin);
|
2017-04-12 19:11:31 -04:00
|
|
|
immUniform1i("image", 0);
|
2017-05-08 15:59:00 +02:00
|
|
|
state.do_shader_unbind = true;
|
2017-04-11 16:30:00 +02:00
|
|
|
|
|
|
|
return state;
|
2017-02-24 11:11:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Use the currently bound shader.
|
|
|
|
*
|
|
|
|
* Use immDrawPixelsTexSetup to bind the shader you
|
|
|
|
* want before calling immDrawPixelsTex.
|
|
|
|
*
|
|
|
|
* If using a special shader double check it uses the same
|
|
|
|
* attributes "pos" "texCoord" and uniform "image".
|
2017-02-24 01:15:21 +01:00
|
|
|
*
|
2017-02-24 11:11:43 +01:00
|
|
|
* If color is NULL then use white by default
|
|
|
|
*
|
|
|
|
* Be also aware that this function unbinds the shader when
|
|
|
|
* it's finished.
|
|
|
|
* */
|
2017-04-11 16:30:00 +02:00
|
|
|
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
|
|
|
|
float x, float y, int img_w, int img_h,
|
2017-02-10 16:13:56 +01:00
|
|
|
int format, int type, int zoomfilter, void *rect,
|
|
|
|
float scaleX, float scaleY,
|
|
|
|
float clip_min_x, float clip_min_y,
|
|
|
|
float clip_max_x, float clip_max_y,
|
|
|
|
float xzoom, float yzoom, float color[4])
|
|
|
|
{
|
|
|
|
unsigned char *uc_rect = (unsigned char *) rect;
|
|
|
|
const float *f_rect = (float *)rect;
|
|
|
|
int subpart_x, subpart_y, tex_w, tex_h;
|
|
|
|
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
|
|
|
|
int texid = get_cached_work_texture(&tex_w, &tex_h);
|
|
|
|
int components;
|
|
|
|
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
|
2017-02-24 01:15:21 +01:00
|
|
|
float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
2017-02-10 16:13:56 +01:00
|
|
|
|
2017-04-04 18:38:26 +02:00
|
|
|
GLint unpack_row_length;
|
|
|
|
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpack_row_length);
|
|
|
|
|
2017-02-10 16:13:56 +01:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w);
|
2018-03-24 20:27:39 +01:00
|
|
|
glActiveTexture(GL_TEXTURE0);
|
2017-02-10 16:13:56 +01:00
|
|
|
glBindTexture(GL_TEXTURE_2D, texid);
|
|
|
|
|
|
|
|
/* don't want nasty border artifacts */
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter);
|
|
|
|
|
|
|
|
/* setup seamless 2=on, 0=off */
|
|
|
|
seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
|
|
|
|
|
|
|
|
offset_x = tex_w - seamless;
|
|
|
|
offset_y = tex_h - seamless;
|
|
|
|
|
|
|
|
nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
|
|
|
|
nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
|
|
|
|
|
|
|
|
if (format == GL_RGBA)
|
|
|
|
components = 4;
|
|
|
|
else if (format == GL_RGB)
|
|
|
|
components = 3;
|
|
|
|
else if (format == GL_RED)
|
|
|
|
components = 1;
|
|
|
|
else {
|
|
|
|
BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == GL_FLOAT) {
|
|
|
|
/* need to set internal format to higher range float */
|
2018-04-24 11:10:30 +02:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, format, GL_FLOAT, NULL);
|
2017-02-10 16:13:56 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* switch to 8bit RGBA for byte buffer */
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL);
|
|
|
|
}
|
|
|
|
|
2017-05-08 16:31:10 +02:00
|
|
|
unsigned int pos = state->pos, texco = state->texco;
|
2017-02-24 01:15:21 +01:00
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
/* optional */
|
|
|
|
/* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
|
|
|
|
* it does not need color.
|
|
|
|
*/
|
|
|
|
if (state->shader != NULL && GPU_shader_get_uniform(state->shader, "color") != -1) {
|
2017-04-12 19:11:31 -04:00
|
|
|
immUniformColor4fv((color) ? color : white);
|
2017-04-11 16:30:00 +02:00
|
|
|
}
|
2017-02-24 01:15:21 +01:00
|
|
|
|
2017-02-10 16:13:56 +01:00
|
|
|
for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) {
|
|
|
|
for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) {
|
|
|
|
int remainder_x = img_w - subpart_x * offset_x;
|
|
|
|
int remainder_y = img_h - subpart_y * offset_y;
|
|
|
|
int subpart_w = (remainder_x < tex_w) ? remainder_x : tex_w;
|
|
|
|
int subpart_h = (remainder_y < tex_h) ? remainder_y : tex_h;
|
|
|
|
int offset_left = (seamless && subpart_x != 0) ? 1 : 0;
|
|
|
|
int offset_bot = (seamless && subpart_y != 0) ? 1 : 0;
|
|
|
|
int offset_right = (seamless && remainder_x > tex_w) ? 1 : 0;
|
|
|
|
int offset_top = (seamless && remainder_y > tex_h) ? 1 : 0;
|
|
|
|
float rast_x = x + subpart_x * offset_x * xzoom;
|
|
|
|
float rast_y = y + subpart_y * offset_y * yzoom;
|
|
|
|
/* check if we already got these because we always get 2 more when doing seamless */
|
|
|
|
if (subpart_w <= seamless || subpart_h <= seamless)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (use_clipping) {
|
|
|
|
if (rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX < clip_min_x ||
|
|
|
|
rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY < clip_min_y)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (rast_x + (float)offset_left * xzoom > clip_max_x ||
|
|
|
|
rast_y + (float)offset_bot * yzoom > clip_max_y)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (type == GL_FLOAT) {
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
|
|
|
|
|
|
|
|
/* add an extra border of pixels so linear looks ok at edges of full image */
|
|
|
|
if (subpart_w < tex_w)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
|
|
|
|
if (subpart_h < tex_h)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
|
|
|
|
if (subpart_w < tex_w && subpart_h < tex_h)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_FLOAT, &f_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + subpart_x * offset_x * components]);
|
|
|
|
|
|
|
|
if (subpart_w < tex_w)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[((size_t)subpart_y) * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
|
|
|
|
if (subpart_h < tex_h)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
|
|
|
|
if (subpart_w < tex_w && subpart_h < tex_h)
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(((size_t)subpart_y) * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
|
|
|
|
}
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
immBegin(GPU_PRIM_TRI_FAN, 4);
|
2018-10-09 11:01:50 +11:00
|
|
|
immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
|
2017-02-10 16:13:56 +01:00
|
|
|
immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
|
|
|
|
|
2018-10-09 11:01:50 +11:00
|
|
|
immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
|
2017-02-10 16:13:56 +01:00
|
|
|
immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom);
|
|
|
|
|
2018-10-09 11:01:50 +11:00
|
|
|
immAttr2f(texco, (float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h);
|
2017-02-10 16:13:56 +01:00
|
|
|
immVertex2f(pos, rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
|
|
|
|
|
2018-10-09 11:01:50 +11:00
|
|
|
immAttr2f(texco, (float)(0 + offset_left) / tex_w, (float)(subpart_h - offset_top) / tex_h);
|
2017-02-10 16:13:56 +01:00
|
|
|
immVertex2f(pos, rast_x + (float)offset_left * xzoom, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
|
|
|
|
immEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-08 15:59:00 +02:00
|
|
|
if (state->do_shader_unbind) {
|
|
|
|
immUnbindProgram();
|
|
|
|
}
|
2017-02-10 16:13:56 +01:00
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2017-04-04 18:38:26 +02:00
|
|
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length);
|
2017-02-10 16:13:56 +01:00
|
|
|
}
|
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
|
|
|
|
float x, float y, int img_w, int img_h,
|
2017-02-10 16:13:56 +01:00
|
|
|
int format, int type, int zoomfilter, void *rect,
|
|
|
|
float scaleX, float scaleY, float xzoom, float yzoom, float color[4])
|
|
|
|
{
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect,
|
2017-02-10 16:13:56 +01:00
|
|
|
scaleX, scaleY, 0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color);
|
|
|
|
}
|
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
void immDrawPixelsTex(IMMDrawPixelsTexState *state,
|
|
|
|
float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect,
|
2017-02-10 16:13:56 +01:00
|
|
|
float xzoom, float yzoom, float color[4])
|
|
|
|
{
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
|
2017-02-10 16:13:56 +01:00
|
|
|
0.0f, 0.0f, 0.0f, 0.0f, xzoom, yzoom, color);
|
|
|
|
}
|
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
|
|
|
|
float x, float y, int img_w, int img_h,
|
2017-02-10 16:13:56 +01:00
|
|
|
int format, int type, int zoomfilter, void *rect,
|
|
|
|
float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y,
|
|
|
|
float xzoom, float yzoom, float color[4])
|
|
|
|
{
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTexScaled_clipping(state, x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f,
|
2017-02-10 16:13:56 +01:00
|
|
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y, xzoom, yzoom, color);
|
|
|
|
}
|
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
/* *************** glPolygonOffset hack ************* */
|
|
|
|
|
2013-12-09 20:59:29 +11:00
|
|
|
/**
|
|
|
|
* \note \a viewdist is only for ortho at the moment.
|
|
|
|
*/
|
2015-04-29 06:08:45 +10:00
|
|
|
void bglPolygonOffset(float viewdist, float dist)
|
2008-01-07 18:03:41 +00:00
|
|
|
{
|
2016-01-04 01:37:55 -05:00
|
|
|
static float winmat[16], offset = 0.0f;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (dist != 0.0f) {
|
2008-01-07 18:03:41 +00:00
|
|
|
float offs;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
// glEnable(GL_POLYGON_OFFSET_FILL);
|
|
|
|
// glPolygonOffset(-1.0, -1.0);
|
|
|
|
|
|
|
|
/* hack below is to mimic polygon offset */
|
2018-07-15 15:27:15 +02:00
|
|
|
GPU_matrix_projection_get(winmat);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2008-01-07 18:03:41 +00:00
|
|
|
/* dist is from camera to center point */
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2015-04-28 20:41:37 +02:00
|
|
|
if (winmat[15] > 0.5f) {
|
2015-04-29 06:08:45 +10:00
|
|
|
#if 1
|
2015-04-29 05:30:30 +10:00
|
|
|
offs = 0.00001f * dist * viewdist; // ortho tweaking
|
|
|
|
#else
|
|
|
|
static float depth_fac = 0.0f;
|
|
|
|
if (depth_fac == 0.0f) {
|
|
|
|
int depthbits;
|
|
|
|
glGetIntegerv(GL_DEPTH_BITS, &depthbits);
|
2015-04-29 05:36:39 +10:00
|
|
|
depth_fac = 1.0f / (float)((1 << depthbits) - 1);
|
2015-04-28 20:41:37 +02:00
|
|
|
}
|
2015-04-29 05:30:30 +10:00
|
|
|
offs = (-1.0 / winmat[10]) * dist * depth_fac;
|
2015-04-29 06:08:45 +10:00
|
|
|
|
|
|
|
UNUSED_VARS(viewdist);
|
2015-04-29 05:30:30 +10:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else {
|
2016-04-27 19:14:13 +10:00
|
|
|
/* This adjustment effectively results in reducing the Z value by 0.25%.
|
|
|
|
*
|
|
|
|
* winmat[14] actually evaluates to `-2 * far * near / (far - near)`,
|
|
|
|
* is very close to -0.2 with default clip range, and is used as the coefficient multiplied by `w / z`,
|
|
|
|
* thus controlling the z dependent part of the depth value.
|
|
|
|
*/
|
|
|
|
offs = winmat[14] * -0.0025f * dist;
|
2015-04-28 20:41:37 +02:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 15:43:59 +00:00
|
|
|
winmat[14] -= offs;
|
|
|
|
offset += offs;
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-05-08 15:43:59 +00:00
|
|
|
winmat[14] += offset;
|
|
|
|
offset = 0.0;
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
2017-03-22 14:48:47 -04:00
|
|
|
|
2018-07-15 15:27:15 +02:00
|
|
|
GPU_matrix_projection_set(winmat);
|
2008-01-07 18:03:41 +00:00
|
|
|
}
|
|
|
|
|
2013-04-02 17:28:37 +00:00
|
|
|
/* **** Color management helper functions for GLSL display/transform ***** */
|
|
|
|
|
|
|
|
/* Draw given image buffer on a screen using GLSL for display transform */
|
2016-05-06 16:54:07 +02:00
|
|
|
void glaDrawImBuf_glsl_clipping(ImBuf *ibuf, float x, float y, int zoomfilter,
|
|
|
|
ColorManagedViewSettings *view_settings,
|
|
|
|
ColorManagedDisplaySettings *display_settings,
|
|
|
|
float clip_min_x, float clip_min_y,
|
2017-02-24 01:15:21 +01:00
|
|
|
float clip_max_x, float clip_max_y,
|
|
|
|
float zoom_x, float zoom_y)
|
2013-04-02 17:28:37 +00:00
|
|
|
{
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
bool force_fallback = false;
|
2013-04-02 17:28:37 +00:00
|
|
|
bool need_fallback = true;
|
|
|
|
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
/* Early out */
|
|
|
|
if (ibuf->rect == NULL && ibuf->rect_float == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Single channel images could not be transformed using GLSL yet */
|
2013-04-25 12:02:56 +00:00
|
|
|
force_fallback |= ibuf->channels == 1;
|
2013-04-03 09:08:02 +00:00
|
|
|
|
2013-04-12 10:52:47 +00:00
|
|
|
/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
|
2013-04-29 15:50:12 +00:00
|
|
|
force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
|
2013-04-12 10:52:47 +00:00
|
|
|
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
/* Try to draw buffer using GLSL display transform */
|
|
|
|
if (force_fallback == false) {
|
|
|
|
int ok;
|
|
|
|
|
2017-04-11 16:30:00 +02:00
|
|
|
IMMDrawPixelsTexState state = {0};
|
2017-05-08 15:59:00 +02:00
|
|
|
/* We want GLSL state to be fully handled by OCIO. */
|
|
|
|
state.do_shader_unbind = false;
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTexSetupAttributes(&state);
|
|
|
|
|
2013-04-04 12:20:13 +00:00
|
|
|
if (ibuf->rect_float) {
|
|
|
|
if (ibuf->float_colorspace) {
|
|
|
|
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
|
2013-12-13 12:36:45 +06:00
|
|
|
ibuf->float_colorspace,
|
|
|
|
ibuf->dither, true);
|
2013-04-04 12:20:13 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-12-13 12:36:45 +06:00
|
|
|
ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings,
|
|
|
|
ibuf->dither, true);
|
2013-04-04 12:20:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
|
2013-12-13 12:36:45 +06:00
|
|
|
ibuf->rect_colorspace,
|
|
|
|
ibuf->dither, false);
|
2013-04-04 12:20:13 +00:00
|
|
|
}
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
|
|
|
|
if (ok) {
|
|
|
|
if (ibuf->rect_float) {
|
2013-04-03 16:21:14 +00:00
|
|
|
int format = 0;
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
|
|
|
|
if (ibuf->channels == 3)
|
|
|
|
format = GL_RGB;
|
|
|
|
else if (ibuf->channels == 4)
|
|
|
|
format = GL_RGBA;
|
|
|
|
else
|
|
|
|
BLI_assert(!"Incompatible number of channels for GLSL display");
|
|
|
|
|
2013-04-03 16:21:14 +00:00
|
|
|
if (format != 0) {
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTex_clipping(&state,
|
|
|
|
x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
|
2016-05-06 16:54:07 +02:00
|
|
|
zoomfilter, ibuf->rect_float,
|
2017-02-24 01:15:21 +01:00
|
|
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y,
|
|
|
|
zoom_x, zoom_y, NULL);
|
2013-04-03 16:21:14 +00:00
|
|
|
}
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
}
|
|
|
|
else if (ibuf->rect) {
|
|
|
|
/* ibuf->rect is always RGBA */
|
2017-04-11 16:30:00 +02:00
|
|
|
immDrawPixelsTex_clipping(&state,
|
|
|
|
x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
|
2016-05-06 16:54:07 +02:00
|
|
|
zoomfilter, ibuf->rect,
|
2017-02-24 01:15:21 +01:00
|
|
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y,
|
|
|
|
zoom_x, zoom_y, NULL);
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
}
|
2013-04-02 17:28:37 +00:00
|
|
|
|
|
|
|
IMB_colormanagement_finish_glsl_draw();
|
|
|
|
|
|
|
|
need_fallback = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bunch of fixes for GLSL display transform
- GLSL shader wasn't aware of alpha predivide option,
always assuming alpha is straight. Gave wrong results
when displaying transparent float buffers.
- GLSL display wasn't aware of float buffers with number
of channels different from 4, crashing when trying to
display image with different number of channels.
This required a bit larger changes, namely now it's
possible to pass format (GL_RGB, GL_RGBAm GL_LUMINANCE)
to glaDrawPixelsTex, This also implied adding format to
glaDrawPixelsAuto and modifying all places where this
functions are called.
Now GLSL will handle both 3 and 4 channels buffers,
single channel images are handled by CPU.
- Replaced hack for render result displaying with a bit
different hack.
Namely CPU conversion will happen only during render,
once render is done GLSL would be used for displaying
render result on a screen.
This is so because of the way renderer updates parts
of the image -- it happens without respect to active
render layer in image user. This is harmless because
only display buffer is modifying, but this is tricky
because we don't have original buffer opened during
rendering.
One more related fix here was about when rendering
multiple layers, wrong image would be displaying when
rendering is done. Added a signal to invalidate
display buffer once rendering is done (only happens
when using multiple layers). This solves issue with
wrong buffer stuck on the display when using regular
CPU display space transform and if GLSL is available
it'll make image displayed with a GLSL shader.
- As an additional change, byte buffers now also uses
GLSL display transform.
So now only dutehr and RGB curves are stoppers for
using GLSL for all kind of display transforms.
2013-04-03 15:59:54 +00:00
|
|
|
/* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */
|
2013-04-02 17:28:37 +00:00
|
|
|
if (need_fallback) {
|
|
|
|
unsigned char *display_buffer;
|
|
|
|
void *cache_handle;
|
|
|
|
|
2013-04-04 12:20:13 +00:00
|
|
|
display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);
|
2013-04-02 17:28:37 +00:00
|
|
|
|
2016-05-06 16:54:07 +02:00
|
|
|
if (display_buffer) {
|
2017-04-11 16:30:00 +02:00
|
|
|
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
|
|
|
|
immDrawPixelsTex_clipping(&state,
|
|
|
|
x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
|
2017-02-24 01:15:21 +01:00
|
|
|
zoomfilter, display_buffer,
|
|
|
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y,
|
|
|
|
zoom_x, zoom_y, NULL);
|
2016-05-06 16:54:07 +02:00
|
|
|
}
|
2013-04-02 17:28:37 +00:00
|
|
|
|
|
|
|
IMB_display_buffer_release(cache_handle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-06 16:54:07 +02:00
|
|
|
void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
|
|
|
|
ColorManagedViewSettings *view_settings,
|
2017-02-24 01:15:21 +01:00
|
|
|
ColorManagedDisplaySettings *display_settings,
|
|
|
|
float zoom_x, float zoom_y)
|
2016-05-06 16:54:07 +02:00
|
|
|
{
|
|
|
|
glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings,
|
2017-02-24 01:15:21 +01:00
|
|
|
0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
|
2016-05-06 16:54:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void glaDrawImBuf_glsl_ctx_clipping(const bContext *C,
|
|
|
|
ImBuf *ibuf,
|
|
|
|
float x, float y,
|
|
|
|
int zoomfilter,
|
|
|
|
float clip_min_x, float clip_min_y,
|
2017-02-24 01:15:21 +01:00
|
|
|
float clip_max_x, float clip_max_y,
|
|
|
|
float zoom_x, float zoom_y)
|
2013-04-04 12:20:13 +00:00
|
|
|
{
|
|
|
|
ColorManagedViewSettings *view_settings;
|
|
|
|
ColorManagedDisplaySettings *display_settings;
|
|
|
|
|
|
|
|
IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
|
|
|
|
|
2016-05-06 16:54:07 +02:00
|
|
|
glaDrawImBuf_glsl_clipping(ibuf, x, y, zoomfilter, view_settings, display_settings,
|
2017-02-24 01:15:21 +01:00
|
|
|
clip_min_x, clip_min_y, clip_max_x, clip_max_y,
|
|
|
|
zoom_x, zoom_y);
|
2016-05-06 16:54:07 +02:00
|
|
|
}
|
|
|
|
|
2017-02-24 01:15:21 +01:00
|
|
|
void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter,
|
|
|
|
float zoom_x, float zoom_y)
|
2016-05-06 16:54:07 +02:00
|
|
|
{
|
2017-02-24 01:15:21 +01:00
|
|
|
glaDrawImBuf_glsl_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
|
2013-04-04 12:20:13 +00:00
|
|
|
}
|
2013-12-01 14:30:22 +11:00
|
|
|
|
2017-04-05 18:30:14 +10:00
|
|
|
/* don't move to GPU_immediate_util.h because this uses user-prefs
|
|
|
|
* and isn't very low level */
|
2017-02-24 00:16:46 -03:00
|
|
|
void immDrawBorderCorners(unsigned int pos, const rcti *border, float zoomx, float zoomy)
|
|
|
|
{
|
|
|
|
float delta_x = 4.0f * UI_DPI_FAC / zoomx;
|
|
|
|
float delta_y = 4.0f * UI_DPI_FAC / zoomy;
|
|
|
|
|
|
|
|
delta_x = min_ff(delta_x, border->xmax - border->xmin);
|
|
|
|
delta_y = min_ff(delta_y, border->ymax - border->ymin);
|
|
|
|
|
|
|
|
/* left bottom corner */
|
2018-07-18 00:12:21 +02:00
|
|
|
immBegin(GPU_PRIM_LINE_STRIP, 3);
|
2017-02-24 00:16:46 -03:00
|
|
|
immVertex2f(pos, border->xmin, border->ymin + delta_y);
|
|
|
|
immVertex2f(pos, border->xmin, border->ymin);
|
|
|
|
immVertex2f(pos, border->xmin + delta_x, border->ymin);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
/* left top corner */
|
2018-07-18 00:12:21 +02:00
|
|
|
immBegin(GPU_PRIM_LINE_STRIP, 3);
|
2017-02-24 00:16:46 -03:00
|
|
|
immVertex2f(pos, border->xmin, border->ymax - delta_y);
|
|
|
|
immVertex2f(pos, border->xmin, border->ymax);
|
|
|
|
immVertex2f(pos, border->xmin + delta_x, border->ymax);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
/* right bottom corner */
|
2018-07-18 00:12:21 +02:00
|
|
|
immBegin(GPU_PRIM_LINE_STRIP, 3);
|
2017-02-24 00:16:46 -03:00
|
|
|
immVertex2f(pos, border->xmax - delta_x, border->ymin);
|
|
|
|
immVertex2f(pos, border->xmax, border->ymin);
|
|
|
|
immVertex2f(pos, border->xmax, border->ymin + delta_y);
|
|
|
|
immEnd();
|
|
|
|
|
|
|
|
/* right top corner */
|
2018-07-18 00:12:21 +02:00
|
|
|
immBegin(GPU_PRIM_LINE_STRIP, 3);
|
2017-02-24 00:16:46 -03:00
|
|
|
immVertex2f(pos, border->xmax - delta_x, border->ymax);
|
|
|
|
immVertex2f(pos, border->xmax, border->ymax);
|
|
|
|
immVertex2f(pos, border->xmax, border->ymax - delta_y);
|
|
|
|
immEnd();
|
|
|
|
}
|