2012-01-19 02:06:09 +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
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* 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,
|
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2009 by Nicholas Bishop
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Jason Wilkins, Tom Musgrove.
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** \file blender/editors/sculpt_paint/paint_cursor.c
|
|
|
|
|
* \ingroup edsculpt
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_math.h"
|
2012-08-21 20:34:05 +00:00
|
|
|
#include "BLI_rect.h"
|
2012-01-19 02:06:09 +00:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
|
|
|
|
#include "DNA_brush_types.h"
|
|
|
|
|
#include "DNA_color_types.h"
|
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
|
#include "DNA_userdef_types.h"
|
|
|
|
|
|
|
|
|
|
#include "BKE_brush.h"
|
|
|
|
|
#include "BKE_context.h"
|
2013-01-21 08:49:42 +00:00
|
|
|
#include "BKE_image.h"
|
2012-01-19 02:06:09 +00:00
|
|
|
#include "BKE_paint.h"
|
2013-04-12 21:58:18 +00:00
|
|
|
#include "BKE_colortools.h"
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
|
|
|
|
#include "BIF_glutil.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_view3d.h"
|
|
|
|
|
|
|
|
|
|
#include "paint_intern.h"
|
|
|
|
|
/* still needed for sculpt_stroke_get_location, should be
|
2012-03-03 16:31:46 +00:00
|
|
|
* removed eventually (TODO) */
|
2012-01-19 02:06:09 +00:00
|
|
|
#include "sculpt_intern.h"
|
|
|
|
|
|
|
|
|
|
/* TODOs:
|
2012-03-03 16:31:46 +00:00
|
|
|
*
|
|
|
|
|
* Some of the cursor drawing code is doing non-draw stuff
|
|
|
|
|
* (e.g. updating the brush rake angle). This should be cleaned up
|
|
|
|
|
* still.
|
|
|
|
|
*
|
|
|
|
|
* There is also some ugliness with sculpt-specific code.
|
2012-01-19 02:06:09 +00:00
|
|
|
*/
|
|
|
|
|
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
typedef struct TexSnapshot {
|
2013-04-22 20:46:18 +00:00
|
|
|
GLuint overlay_texture;
|
2012-01-19 02:06:09 +00:00
|
|
|
int winx;
|
|
|
|
|
int winy;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
bool init;
|
2013-04-22 20:46:18 +00:00
|
|
|
int old_size;
|
|
|
|
|
int old_zoom;
|
|
|
|
|
bool old_col;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
} TexSnapshot;
|
|
|
|
|
|
|
|
|
|
typedef struct CurveSnapshot {
|
|
|
|
|
int BKE_brush_size_get;
|
2012-01-19 02:06:09 +00:00
|
|
|
int curve_changed_timestamp;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
bool init;
|
|
|
|
|
} CurveSnapshot;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
return (/* make brush smaller shouldn't cause a resample */
|
|
|
|
|
//(mtex->brush_map_mode != MTEX_MAP_MODE_VIEW ||
|
|
|
|
|
//(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) &&
|
2012-03-28 03:47:33 +00:00
|
|
|
|
2013-04-13 00:43:49 +00:00
|
|
|
(mtex->brush_map_mode != MTEX_MAP_MODE_TILED ||
|
2013-04-23 05:29:06 +00:00
|
|
|
(vc->ar->winx == snap->winx &&
|
|
|
|
|
vc->ar->winy == snap->winy)) &&
|
2013-04-22 20:46:18 +00:00
|
|
|
snap->old_zoom == zoom &&
|
2013-04-23 05:29:06 +00:00
|
|
|
snap->old_col == col
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
2013-04-22 20:46:18 +00:00
|
|
|
snap->old_zoom = zoom;
|
2012-01-19 02:06:09 +00:00
|
|
|
snap->winx = vc->ar->winx;
|
|
|
|
|
snap->winy = vc->ar->winy;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
|
|
|
|
static int init = 0;
|
2013-04-22 20:46:18 +00:00
|
|
|
static TexSnapshot primary_snap = {0};
|
|
|
|
|
static TexSnapshot secondary_snap = {0};
|
|
|
|
|
TexSnapshot *target;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
|
2013-04-16 15:02:41 +00:00
|
|
|
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
|
2012-03-28 03:47:33 +00:00
|
|
|
GLubyte *buffer = NULL;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
int size;
|
|
|
|
|
int j;
|
|
|
|
|
int refresh;
|
2013-03-31 03:28:46 +00:00
|
|
|
GLenum format = col ? GL_RGBA : GL_ALPHA;
|
2013-04-22 20:46:18 +00:00
|
|
|
OverlayControlFlags invalid = (primary) ? (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY) :
|
|
|
|
|
(overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
|
|
|
|
|
|
|
|
|
|
target = (primary) ? &primary_snap : &secondary_snap;
|
2013-04-23 11:02:36 +00:00
|
|
|
|
2012-01-19 02:06:09 +00:00
|
|
|
refresh =
|
2013-04-22 20:46:18 +00:00
|
|
|
!target->overlay_texture ||
|
|
|
|
|
(invalid != 0) ||
|
|
|
|
|
!same_tex_snap(target, mtex, vc, col, zoom);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
if (refresh) {
|
2013-01-21 08:49:42 +00:00
|
|
|
struct ImagePool *pool = NULL;
|
2013-03-31 00:38:50 +00:00
|
|
|
/* stencil is rotated later */
|
2013-04-22 20:46:18 +00:00
|
|
|
const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
|
|
|
|
|
-mtex->rot : 0;
|
2013-03-31 00:38:50 +00:00
|
|
|
|
2013-03-29 14:02:28 +00:00
|
|
|
float radius = BKE_brush_size_get(vc->scene, br) * zoom;
|
2013-01-21 08:49:42 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
make_tex_snap(target, vc, zoom);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
|
2012-05-05 00:58:22 +00:00
|
|
|
int s = BKE_brush_size_get(vc->scene, br);
|
2012-01-19 02:06:09 +00:00
|
|
|
int r = 1;
|
|
|
|
|
|
|
|
|
|
for (s >>= 1; s > 0; s >>= 1)
|
|
|
|
|
r++;
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
size = (1 << r);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
if (size < 256)
|
|
|
|
|
size = 256;
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (size < target->old_size)
|
|
|
|
|
size = target->old_size;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
size = 512;
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (target->old_size != size) {
|
|
|
|
|
if (target->overlay_texture) {
|
|
|
|
|
glDeleteTextures(1, &target->overlay_texture);
|
|
|
|
|
target->overlay_texture = 0;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init = 0;
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
target->old_size = size;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
2013-03-31 00:38:50 +00:00
|
|
|
if (col)
|
|
|
|
|
buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex");
|
|
|
|
|
else
|
|
|
|
|
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-23 11:02:36 +00:00
|
|
|
pool = BKE_image_pool_new();
|
2013-01-21 08:49:42 +00:00
|
|
|
|
2013-01-16 03:20:36 +00:00
|
|
|
#pragma omp parallel for schedule(static)
|
2012-03-28 03:47:33 +00:00
|
|
|
for (j = 0; j < size; j++) {
|
2012-01-19 02:06:09 +00:00
|
|
|
int i;
|
|
|
|
|
float y;
|
|
|
|
|
float len;
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
for (i = 0; i < size; i++) {
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
// largely duplicated from tex_strength
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
int index = j * size + i;
|
2012-01-19 02:06:09 +00:00
|
|
|
float x;
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
x = (float)i / size;
|
|
|
|
|
y = (float)j / size;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
|
2012-01-19 02:06:09 +00:00
|
|
|
x *= vc->ar->winx / radius;
|
|
|
|
|
y *= vc->ar->winy / radius;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-03-13 03:46:22 +00:00
|
|
|
x -= 0.5f;
|
|
|
|
|
y -= 0.5f;
|
|
|
|
|
|
2012-01-19 02:06:09 +00:00
|
|
|
x *= 2;
|
|
|
|
|
y *= 2;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
len = sqrtf(x * x + y * y);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) {
|
2012-01-19 02:06:09 +00:00
|
|
|
/* it is probably worth optimizing for those cases where
|
2012-03-03 16:31:46 +00:00
|
|
|
* the texture is not rotated by skipping the calls to
|
|
|
|
|
* atan2, sqrtf, sin, and cos. */
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
|
|
|
|
|
const float angle = atan2f(y, x) + rotation;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
x = len * cosf(angle);
|
|
|
|
|
y = len * sinf(angle);
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
x *= mtex->size[0];
|
|
|
|
|
y *= mtex->size[1];
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
x += mtex->ofs[0];
|
|
|
|
|
y += mtex->ofs[1];
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-03-31 00:38:50 +00:00
|
|
|
if (col) {
|
|
|
|
|
float rgba[4];
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-23 11:02:36 +00:00
|
|
|
paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-03-31 03:28:46 +00:00
|
|
|
buffer[index * 4] = rgba[0] * 255;
|
|
|
|
|
buffer[index * 4 + 1] = rgba[1] * 255;
|
|
|
|
|
buffer[index * 4 + 2] = rgba[2] * 255;
|
|
|
|
|
buffer[index * 4 + 3] = rgba[3] * 255;
|
2013-03-31 00:38:50 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-04-23 11:02:36 +00:00
|
|
|
float avg = paint_get_tex_pixel(mtex, x, y, pool);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-03-31 00:38:50 +00:00
|
|
|
avg += br->texture_sample_bias;
|
|
|
|
|
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
/* clamp to avoid precision overflow */
|
2013-04-13 00:43:49 +00:00
|
|
|
CLAMP(avg, 0.0f, 1.0f);
|
2013-03-31 00:38:50 +00:00
|
|
|
buffer[index] = 255 - (GLubyte)(255 * avg);
|
|
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-03-31 00:38:50 +00:00
|
|
|
if (col) {
|
2013-03-31 03:28:46 +00:00
|
|
|
buffer[index * 4] = 0;
|
|
|
|
|
buffer[index * 4 + 1] = 0;
|
|
|
|
|
buffer[index * 4 + 2] = 0;
|
|
|
|
|
buffer[index * 4 + 3] = 0;
|
2013-03-31 00:38:50 +00:00
|
|
|
}
|
2013-03-31 03:28:46 +00:00
|
|
|
else {
|
2013-03-31 00:38:50 +00:00
|
|
|
buffer[index] = 0;
|
2013-03-31 03:28:46 +00:00
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-21 08:49:42 +00:00
|
|
|
if (pool)
|
|
|
|
|
BKE_image_pool_free(pool);
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (!target->overlay_texture)
|
|
|
|
|
glGenTextures(1, &target->overlay_texture);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-04-22 20:46:18 +00:00
|
|
|
size = target->old_size;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
glBindTexture(GL_TEXTURE_2D, target->overlay_texture);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
if (refresh) {
|
2013-04-22 20:46:18 +00:00
|
|
|
if (!init || (target->old_col != col)) {
|
2013-03-31 00:38:50 +00:00
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
|
2012-01-19 02:06:09 +00:00
|
|
|
init = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2013-03-31 00:38:50 +00:00
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
|
MEM_freeN(buffer);
|
2013-03-31 00:38:50 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
target->old_col = col;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
|
2012-01-19 02:06:09 +00:00
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
BKE_paint_reset_overlay_invalid(invalid);
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
|
2012-01-19 02:06:09 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
|
|
|
|
|
{
|
|
|
|
|
static GLuint overlay_texture = 0;
|
|
|
|
|
static int init = 0;
|
|
|
|
|
static int old_size = -1;
|
|
|
|
|
static int old_zoom = -1;
|
|
|
|
|
|
|
|
|
|
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
|
|
|
|
|
GLubyte *buffer = NULL;
|
|
|
|
|
|
|
|
|
|
int size;
|
|
|
|
|
int j;
|
|
|
|
|
int refresh;
|
|
|
|
|
|
|
|
|
|
refresh =
|
|
|
|
|
!overlay_texture ||
|
|
|
|
|
(overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
|
|
|
|
|
old_zoom != zoom;
|
|
|
|
|
|
|
|
|
|
if (refresh) {
|
|
|
|
|
int s, r;
|
|
|
|
|
|
|
|
|
|
old_zoom = zoom;
|
|
|
|
|
|
|
|
|
|
s = BKE_brush_size_get(vc->scene, br);
|
|
|
|
|
r = 1;
|
|
|
|
|
|
|
|
|
|
for (s >>= 1; s > 0; s >>= 1)
|
|
|
|
|
r++;
|
|
|
|
|
|
|
|
|
|
size = (1 << r);
|
|
|
|
|
|
|
|
|
|
if (size < 256)
|
|
|
|
|
size = 256;
|
|
|
|
|
|
|
|
|
|
if (size < old_size)
|
|
|
|
|
size = old_size;
|
|
|
|
|
|
|
|
|
|
if (old_size != size) {
|
|
|
|
|
if (overlay_texture) {
|
|
|
|
|
glDeleteTextures(1, &overlay_texture);
|
|
|
|
|
overlay_texture = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init = 0;
|
|
|
|
|
|
|
|
|
|
old_size = size;
|
|
|
|
|
}
|
|
|
|
|
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
|
|
|
|
|
|
|
|
|
|
curvemapping_initialize(br->curve);
|
|
|
|
|
|
|
|
|
|
#pragma omp parallel for schedule(static)
|
|
|
|
|
for (j = 0; j < size; j++) {
|
|
|
|
|
int i;
|
|
|
|
|
float y;
|
|
|
|
|
float len;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) {
|
|
|
|
|
|
|
|
|
|
// largely duplicated from tex_strength
|
|
|
|
|
|
|
|
|
|
int index = j * size + i;
|
|
|
|
|
float x;
|
|
|
|
|
|
|
|
|
|
x = (float)i / size;
|
|
|
|
|
y = (float)j / size;
|
|
|
|
|
|
2013-04-22 22:20:38 +00:00
|
|
|
x -= 0.5f;
|
|
|
|
|
y -= 0.5f;
|
2013-04-22 20:46:18 +00:00
|
|
|
|
2013-04-22 22:20:38 +00:00
|
|
|
x *= 2;
|
|
|
|
|
y *= 2;
|
2013-04-22 20:46:18 +00:00
|
|
|
|
|
|
|
|
len = sqrtf(x * x + y * y);
|
|
|
|
|
|
|
|
|
|
if (len <= 1) {
|
2013-04-23 05:29:06 +00:00
|
|
|
float avg = BKE_brush_curve_strength(br, len, 1.0f); /* Falloff curve */
|
2013-04-22 20:46:18 +00:00
|
|
|
|
2013-04-23 05:29:06 +00:00
|
|
|
/* clamp to avoid precision overflow */
|
|
|
|
|
CLAMP(avg, 0.0f, 1.0f);
|
|
|
|
|
buffer[index] = 255 - (GLubyte)(255 * avg);
|
2013-04-22 20:46:18 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
buffer[index] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!overlay_texture)
|
|
|
|
|
glGenTextures(1, &overlay_texture);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
size = old_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, overlay_texture);
|
|
|
|
|
|
|
|
|
|
if (refresh) {
|
|
|
|
|
if (!init) {
|
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
|
|
|
|
|
init = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (buffer)
|
|
|
|
|
MEM_freeN(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
|
|
|
|
|
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
|
|
|
|
|
|
|
|
|
BKE_paint_reset_overlay_invalid(PAINT_INVALID_OVERLAY_CURVE);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-01-19 02:06:09 +00:00
|
|
|
static int project_brush_radius(ViewContext *vc,
|
2012-03-28 03:47:33 +00:00
|
|
|
float radius,
|
|
|
|
|
const float location[3])
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
|
|
|
|
float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2];
|
|
|
|
|
|
|
|
|
|
ED_view3d_global_to_vector(vc->rv3d, location, view);
|
|
|
|
|
|
2012-07-06 23:56:59 +00:00
|
|
|
/* create a vector that is not orthogonal to view */
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
if (fabsf(view[0]) < 0.1f) {
|
|
|
|
|
nonortho[0] = view[0] + 1.0f;
|
|
|
|
|
nonortho[1] = view[1];
|
|
|
|
|
nonortho[2] = view[2];
|
|
|
|
|
}
|
|
|
|
|
else if (fabsf(view[1]) < 0.1f) {
|
|
|
|
|
nonortho[0] = view[0];
|
|
|
|
|
nonortho[1] = view[1] + 1.0f;
|
|
|
|
|
nonortho[2] = view[2];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
nonortho[0] = view[0];
|
|
|
|
|
nonortho[1] = view[1];
|
|
|
|
|
nonortho[2] = view[2] + 1.0f;
|
|
|
|
|
}
|
|
|
|
|
|
2012-07-06 23:56:59 +00:00
|
|
|
/* get a vector in the plane of the view */
|
2012-01-19 02:06:09 +00:00
|
|
|
cross_v3_v3v3(ortho, nonortho, view);
|
|
|
|
|
normalize_v3(ortho);
|
|
|
|
|
|
2012-07-06 23:56:59 +00:00
|
|
|
/* make a point on the surface of the brush tagent to the view */
|
2012-01-19 02:06:09 +00:00
|
|
|
mul_v3_fl(ortho, radius);
|
|
|
|
|
add_v3_v3v3(offset, location, ortho);
|
|
|
|
|
|
2012-07-06 23:56:59 +00:00
|
|
|
/* project the center of the brush, and the tangent point to the view onto the screen */
|
2012-10-07 14:00:18 +00:00
|
|
|
if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
|
|
|
|
|
(ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
|
2012-10-05 03:20:14 +00:00
|
|
|
{
|
|
|
|
|
/* the distance between these points is the size of the projected brush in pixels */
|
|
|
|
|
return len_v2v2(p1, p2);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_assert(0); /* assert because the code that sets up the vectors should disallow this */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-28 03:47:33 +00:00
|
|
|
static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
|
|
|
|
|
int x, int y, int *pixel_radius,
|
|
|
|
|
float location[3])
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Paint *paint = BKE_paint_get_active_from_context(C);
|
2013-03-04 22:55:53 +00:00
|
|
|
float mouse[2];
|
2012-01-19 02:06:09 +00:00
|
|
|
int hit;
|
|
|
|
|
|
2013-03-04 22:55:53 +00:00
|
|
|
mouse[0] = x;
|
|
|
|
|
mouse[1] = y;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (vc->obact->sculpt && vc->obact->sculpt->pbvh &&
|
2013-03-04 22:55:53 +00:00
|
|
|
sculpt_stroke_get_location(C, location, mouse))
|
2012-05-20 19:49:27 +00:00
|
|
|
{
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Brush *brush = BKE_paint_brush(paint);
|
2012-01-19 02:06:09 +00:00
|
|
|
*pixel_radius =
|
2012-03-28 03:47:33 +00:00
|
|
|
project_brush_radius(vc,
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_brush_unprojected_radius_get(scene, brush),
|
2012-03-28 03:47:33 +00:00
|
|
|
location);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
if (*pixel_radius == 0)
|
2012-05-05 00:58:22 +00:00
|
|
|
*pixel_radius = BKE_brush_size_get(scene, brush);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
mul_m4_v3(vc->obact->obmat, location);
|
|
|
|
|
|
|
|
|
|
hit = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-28 03:47:33 +00:00
|
|
|
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Brush *brush = BKE_paint_brush(&sd->paint);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
*pixel_radius = BKE_brush_size_get(scene, brush);
|
2012-01-19 02:06:09 +00:00
|
|
|
hit = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return hit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw an overlay that shows what effect the brush's texture will
|
2012-03-03 16:31:46 +00:00
|
|
|
* have on brush strength */
|
2013-04-22 20:46:18 +00:00
|
|
|
static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
|
|
|
|
|
ViewContext *vc, int x, int y, float zoom, bool col, bool primary)
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
|
|
|
|
rctf quad;
|
|
|
|
|
/* check for overlay mode */
|
2013-03-31 00:38:50 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
MTex *mtex = (primary) ? &brush->mtex : &brush->mask_mtex;
|
|
|
|
|
bool valid = (primary) ? (brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) != 0 :
|
|
|
|
|
(brush->overlay_flags & BRUSH_OVERLAY_SECONDARY) != 0;
|
|
|
|
|
int overlay_alpha = (primary) ? brush->texture_overlay_alpha : brush->mask_overlay_alpha;
|
|
|
|
|
|
2013-04-23 11:02:36 +00:00
|
|
|
if (!(mtex->tex) || !((mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) ||
|
2013-04-22 20:46:18 +00:00
|
|
|
(valid &&
|
2013-04-23 11:02:36 +00:00
|
|
|
ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))))
|
2012-04-28 06:31:57 +00:00
|
|
|
{
|
2012-01-19 02:06:09 +00:00
|
|
|
return;
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (load_tex(brush, vc, zoom, col, primary)) {
|
2012-01-19 02:06:09 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
|
|
|
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
|
glPushMatrix();
|
|
|
|
|
glLoadIdentity();
|
|
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
|
2012-01-19 02:06:09 +00:00
|
|
|
/* brush rotation */
|
|
|
|
|
glTranslatef(0.5, 0.5, 0);
|
2013-03-13 03:46:22 +00:00
|
|
|
glRotatef((double)RAD2DEGF(ups->brush_rotation),
|
2012-03-28 03:47:33 +00:00
|
|
|
0.0, 0.0, 1.0);
|
2012-01-19 02:06:09 +00:00
|
|
|
glTranslatef(-0.5f, -0.5f, 0);
|
|
|
|
|
|
|
|
|
|
/* scale based on tablet pressure */
|
2013-04-22 20:46:18 +00:00
|
|
|
if (primary && ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
|
2012-01-19 02:06:09 +00:00
|
|
|
glTranslatef(0.5f, 0.5f, 0);
|
2013-01-16 03:20:36 +00:00
|
|
|
glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
|
2012-01-19 02:06:09 +00:00
|
|
|
glTranslatef(-0.5f, -0.5f, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-16 03:20:36 +00:00
|
|
|
if (ups->draw_anchored) {
|
|
|
|
|
const float *aim = ups->anchored_initial_mouse;
|
2013-03-13 03:46:22 +00:00
|
|
|
quad.xmin = aim[0] - ups->anchored_size;
|
|
|
|
|
quad.ymin = aim[1] - ups->anchored_size;
|
|
|
|
|
quad.xmax = aim[0] + ups->anchored_size;
|
|
|
|
|
quad.ymax = aim[1] + ups->anchored_size;
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-03-30 09:57:35 +00:00
|
|
|
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
|
2012-01-19 02:06:09 +00:00
|
|
|
quad.xmin = x - radius;
|
|
|
|
|
quad.ymin = y - radius;
|
|
|
|
|
quad.xmax = x + radius;
|
|
|
|
|
quad.ymax = y + radius;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-22 20:46:18 +00:00
|
|
|
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
|
2012-01-19 02:06:09 +00:00
|
|
|
quad.xmin = 0;
|
|
|
|
|
quad.ymin = 0;
|
2012-09-15 11:48:20 +00:00
|
|
|
quad.xmax = BLI_rcti_size_x(&vc->ar->winrct);
|
|
|
|
|
quad.ymax = BLI_rcti_size_y(&vc->ar->winrct);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
2013-04-17 11:16:53 +00:00
|
|
|
/* Stencil code goes here */
|
|
|
|
|
else {
|
2013-04-23 00:06:22 +00:00
|
|
|
if (primary) {
|
|
|
|
|
quad.xmin = -brush->stencil_dimension[0];
|
|
|
|
|
quad.ymin = -brush->stencil_dimension[1];
|
|
|
|
|
quad.xmax = brush->stencil_dimension[0];
|
|
|
|
|
quad.ymax = brush->stencil_dimension[1];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
quad.xmin = -brush->mask_stencil_dimension[0];
|
|
|
|
|
quad.ymin = -brush->mask_stencil_dimension[1];
|
|
|
|
|
quad.xmax = brush->mask_stencil_dimension[0];
|
|
|
|
|
quad.ymax = brush->mask_stencil_dimension[1];
|
|
|
|
|
}
|
2013-03-31 00:38:50 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
glPushMatrix();
|
2013-04-23 00:06:22 +00:00
|
|
|
if (primary)
|
|
|
|
|
glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0);
|
|
|
|
|
else
|
|
|
|
|
glTranslatef(brush->mask_stencil_pos[0], brush->mask_stencil_pos[1], 0);
|
2013-04-22 20:46:18 +00:00
|
|
|
glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
|
2013-03-31 00:38:50 +00:00
|
|
|
glMatrixMode(GL_TEXTURE);
|
|
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-03-31 00:38:50 +00:00
|
|
|
/* set quad color. Colored overlay does not get blending */
|
|
|
|
|
if (col)
|
|
|
|
|
glColor4f(1.0,
|
|
|
|
|
1.0,
|
|
|
|
|
1.0,
|
2013-04-22 20:46:18 +00:00
|
|
|
overlay_alpha / 100.0f);
|
2013-03-31 00:38:50 +00:00
|
|
|
else
|
|
|
|
|
glColor4f(U.sculpt_paint_overlay_col[0],
|
|
|
|
|
U.sculpt_paint_overlay_col[1],
|
|
|
|
|
U.sculpt_paint_overlay_col[2],
|
2013-04-22 20:46:18 +00:00
|
|
|
overlay_alpha / 100.0f);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* draw textured quad */
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
glTexCoord2f(0, 0);
|
|
|
|
|
glVertex2f(quad.xmin, quad.ymin);
|
|
|
|
|
glTexCoord2f(1, 0);
|
|
|
|
|
glVertex2f(quad.xmax, quad.ymin);
|
|
|
|
|
glTexCoord2f(1, 1);
|
|
|
|
|
glVertex2f(quad.xmax, quad.ymax);
|
|
|
|
|
glTexCoord2f(0, 1);
|
|
|
|
|
glVertex2f(quad.xmin, quad.ymax);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glPopMatrix();
|
2013-03-31 00:38:50 +00:00
|
|
|
|
2013-04-22 20:46:18 +00:00
|
|
|
if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
|
2013-03-31 00:38:50 +00:00
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
glPopMatrix();
|
|
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
2013-04-22 20:46:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw an overlay that shows what effect the brush's texture will
|
|
|
|
|
* have on brush strength */
|
|
|
|
|
static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
|
2013-04-23 05:29:06 +00:00
|
|
|
ViewContext *vc, int x, int y, float zoom)
|
2013-04-22 20:46:18 +00:00
|
|
|
{
|
|
|
|
|
rctf quad;
|
|
|
|
|
/* check for overlay mode */
|
|
|
|
|
|
2013-04-23 05:29:06 +00:00
|
|
|
if (!(brush->overlay_flags & BRUSH_OVERLAY_CURSOR)) {
|
2013-04-22 20:46:18 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (load_tex_cursor(brush, vc, zoom)) {
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
|
|
|
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
|
|
|
glDepthMask(GL_FALSE);
|
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
|
|
|
|
|
|
|
|
/* scale based on tablet pressure */
|
|
|
|
|
if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
|
|
|
|
|
glTranslatef(0.5f, 0.5f, 0);
|
|
|
|
|
glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
|
|
|
|
|
glTranslatef(-0.5f, -0.5f, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ups->draw_anchored) {
|
|
|
|
|
const float *aim = ups->anchored_initial_mouse;
|
|
|
|
|
quad.xmin = aim[0] - ups->anchored_size;
|
|
|
|
|
quad.ymin = aim[1] - ups->anchored_size;
|
|
|
|
|
quad.xmax = aim[0] + ups->anchored_size;
|
|
|
|
|
quad.ymax = aim[1] + ups->anchored_size;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
|
|
|
|
|
quad.xmin = x - radius;
|
|
|
|
|
quad.ymin = y - radius;
|
|
|
|
|
quad.xmax = x + radius;
|
|
|
|
|
quad.ymax = y + radius;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glColor4f(U.sculpt_paint_overlay_col[0],
|
|
|
|
|
U.sculpt_paint_overlay_col[1],
|
|
|
|
|
U.sculpt_paint_overlay_col[2],
|
|
|
|
|
brush->cursor_overlay_alpha / 100.0f);
|
|
|
|
|
|
|
|
|
|
/* draw textured quad */
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
glTexCoord2f(0, 0);
|
|
|
|
|
glVertex2f(quad.xmin, quad.ymin);
|
|
|
|
|
glTexCoord2f(1, 0);
|
|
|
|
|
glVertex2f(quad.xmax, quad.ymin);
|
|
|
|
|
glTexCoord2f(1, 1);
|
|
|
|
|
glVertex2f(quad.xmax, quad.ymax);
|
|
|
|
|
glTexCoord2f(0, 1);
|
|
|
|
|
glVertex2f(quad.xmin, quad.ymax);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
|
|
|
|
|
ViewContext *vc, int x, int y, float zoom, PaintMode mode)
|
|
|
|
|
{
|
|
|
|
|
/* color means that primary brush texture is colured and secondary is used for alpha/mask control */
|
|
|
|
|
bool col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true: false;
|
2013-04-23 00:32:51 +00:00
|
|
|
OverlayControlFlags flags = BKE_paint_get_overlay_flags();
|
2013-04-22 20:46:18 +00:00
|
|
|
/* save lots of GL state
|
|
|
|
|
* TODO: check on whether all of these are needed? */
|
|
|
|
|
glPushAttrib(GL_COLOR_BUFFER_BIT |
|
|
|
|
|
GL_CURRENT_BIT |
|
|
|
|
|
GL_DEPTH_BUFFER_BIT |
|
|
|
|
|
GL_ENABLE_BIT |
|
|
|
|
|
GL_LINE_BIT |
|
|
|
|
|
GL_POLYGON_BIT |
|
|
|
|
|
GL_STENCIL_BUFFER_BIT |
|
|
|
|
|
GL_TRANSFORM_BIT |
|
|
|
|
|
GL_VIEWPORT_BIT |
|
|
|
|
|
GL_TEXTURE_BIT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* coloured overlay should be drawn separately */
|
|
|
|
|
if (col) {
|
2013-04-23 00:32:51 +00:00
|
|
|
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY))
|
|
|
|
|
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, true, true);
|
|
|
|
|
if (!(flags & PAINT_OVERLAY_OVERRIDE_SECONDARY))
|
|
|
|
|
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, false);
|
|
|
|
|
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
|
|
|
|
|
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
|
2013-04-23 05:29:06 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-04-23 00:32:51 +00:00
|
|
|
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY))
|
|
|
|
|
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, true);
|
|
|
|
|
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
|
|
|
|
|
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
|
2013-04-22 20:46:18 +00:00
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
glPopAttrib();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Special actions taken when paint cursor goes over mesh */
|
|
|
|
|
/* TODO: sculpt only for now */
|
2013-01-16 03:20:36 +00:00
|
|
|
static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc,
|
2012-03-28 03:47:33 +00:00
|
|
|
const float location[3])
|
2012-01-19 02:06:09 +00:00
|
|
|
{
|
|
|
|
|
float unprojected_radius, projected_radius;
|
|
|
|
|
|
|
|
|
|
/* update the brush's cached 3D radius */
|
2012-05-05 00:58:22 +00:00
|
|
|
if (!BKE_brush_use_locked_size(vc->scene, brush)) {
|
2012-01-19 02:06:09 +00:00
|
|
|
/* get 2D brush radius */
|
2013-01-16 03:20:36 +00:00
|
|
|
if (ups->draw_anchored)
|
|
|
|
|
projected_radius = ups->anchored_size;
|
2012-01-19 02:06:09 +00:00
|
|
|
else {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (brush->flag & BRUSH_ANCHORED)
|
2012-01-19 02:06:09 +00:00
|
|
|
projected_radius = 8;
|
|
|
|
|
else
|
2012-05-05 00:58:22 +00:00
|
|
|
projected_radius = BKE_brush_size_get(vc->scene, brush);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* convert brush radius from 2D to 3D */
|
|
|
|
|
unprojected_radius = paint_calc_object_space_radius(vc, location,
|
2012-03-28 03:47:33 +00:00
|
|
|
projected_radius);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* scale 3D brush radius by pressure */
|
2013-01-16 03:20:36 +00:00
|
|
|
if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush))
|
|
|
|
|
unprojected_radius *= ups->pressure_value;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* set cached value in either Brush or UnifiedPaintSettings */
|
2012-05-05 00:58:22 +00:00
|
|
|
BKE_brush_unprojected_radius_set(vc->scene, brush, unprojected_radius);
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2013-01-16 03:20:36 +00:00
|
|
|
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Paint *paint = BKE_paint_get_active_from_context(C);
|
|
|
|
|
Brush *brush = BKE_paint_brush(paint);
|
2012-01-19 02:06:09 +00:00
|
|
|
ViewContext vc;
|
2013-03-31 00:38:50 +00:00
|
|
|
PaintMode mode;
|
2012-01-19 02:06:09 +00:00
|
|
|
float final_radius;
|
|
|
|
|
float translation[2];
|
|
|
|
|
float outline_alpha, *outline_col;
|
2013-03-29 14:02:28 +00:00
|
|
|
float zoomx, zoomy;
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* check that brush drawing is enabled */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!(paint->flags & PAINT_SHOW_BRUSH))
|
2012-01-19 02:06:09 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* can't use stroke vc here because this will be called during
|
2012-03-03 16:31:46 +00:00
|
|
|
* mouse over too, not just during a stroke */
|
2012-01-19 02:06:09 +00:00
|
|
|
view3d_set_viewcontext(C, &vc);
|
|
|
|
|
|
2013-03-29 14:02:28 +00:00
|
|
|
get_imapaint_zoom(C, &zoomx, &zoomy);
|
|
|
|
|
zoomx = max_ff(zoomx, zoomy);
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
mode = BKE_paintmode_get_active_from_context(C);
|
2013-03-29 14:02:28 +00:00
|
|
|
|
|
|
|
|
/* set various defaults */
|
|
|
|
|
translation[0] = x;
|
|
|
|
|
translation[1] = y;
|
|
|
|
|
outline_alpha = 0.5;
|
|
|
|
|
outline_col = brush->add_col;
|
2013-03-30 09:57:35 +00:00
|
|
|
final_radius = BKE_brush_size_get(scene, brush) * zoomx;
|
2013-03-29 14:02:28 +00:00
|
|
|
|
2013-03-13 03:46:22 +00:00
|
|
|
if (brush->flag & BRUSH_RAKE)
|
|
|
|
|
/* here, translation contains the mouse coordinates. */
|
|
|
|
|
paint_calculate_rake_rotation(ups, translation);
|
2013-03-29 14:02:28 +00:00
|
|
|
else if (!(brush->flag & BRUSH_ANCHORED))
|
|
|
|
|
ups->brush_rotation = 0.0;
|
2013-03-13 03:46:22 +00:00
|
|
|
|
|
|
|
|
/* draw overlay */
|
2013-04-23 00:32:51 +00:00
|
|
|
paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
|
2013-03-13 03:46:22 +00:00
|
|
|
|
2012-01-19 02:06:09 +00:00
|
|
|
/* TODO: as sculpt and other paint modes are unified, this
|
2012-03-03 16:31:46 +00:00
|
|
|
* special mode of drawing will go away */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (vc.obact->sculpt) {
|
2012-01-19 02:06:09 +00:00
|
|
|
float location[3];
|
|
|
|
|
int pixel_radius, hit;
|
|
|
|
|
|
|
|
|
|
/* test if brush is over the mesh */
|
|
|
|
|
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
|
|
|
|
|
|
2012-05-05 00:58:22 +00:00
|
|
|
if (BKE_brush_use_locked_size(scene, brush))
|
|
|
|
|
BKE_brush_size_set(scene, brush, pixel_radius);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* check if brush is subtracting, use different color then */
|
|
|
|
|
/* TODO: no way currently to know state of pen flip or
|
2012-03-03 16:31:46 +00:00
|
|
|
* invert key modifier without starting a stroke */
|
2012-03-24 06:38:07 +00:00
|
|
|
if ((!(brush->flag & BRUSH_INVERTED) ^
|
2012-03-28 03:47:33 +00:00
|
|
|
!(brush->flag & BRUSH_DIR_IN)) &&
|
|
|
|
|
ELEM5(brush->sculpt_tool, SCULPT_TOOL_DRAW,
|
|
|
|
|
SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY,
|
|
|
|
|
SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE))
|
2012-04-28 06:31:57 +00:00
|
|
|
{
|
2012-01-19 02:06:09 +00:00
|
|
|
outline_col = brush->sub_col;
|
2012-04-28 06:31:57 +00:00
|
|
|
}
|
2012-01-19 02:06:09 +00:00
|
|
|
|
|
|
|
|
/* only do if brush is over the mesh */
|
2012-03-24 06:38:07 +00:00
|
|
|
if (hit)
|
2013-01-16 03:20:36 +00:00
|
|
|
paint_cursor_on_hit(ups, brush, &vc, location);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2013-01-16 03:20:36 +00:00
|
|
|
if (ups->draw_anchored) {
|
|
|
|
|
final_radius = ups->anchored_size;
|
2013-03-05 20:25:08 +00:00
|
|
|
translation[0] = ups->anchored_initial_mouse[0];
|
|
|
|
|
translation[1] = ups->anchored_initial_mouse[1];
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make lines pretty */
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
|
|
|
|
|
|
/* set brush color */
|
|
|
|
|
glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha);
|
|
|
|
|
|
|
|
|
|
/* draw brush outline */
|
|
|
|
|
glTranslatef(translation[0], translation[1], 0);
|
2013-01-16 19:22:15 +00:00
|
|
|
|
|
|
|
|
/* draw an inner brush */
|
2013-01-17 04:24:22 +00:00
|
|
|
if (ups->draw_pressure && BKE_brush_use_size_pressure(scene, brush)) {
|
2013-01-16 23:37:47 +00:00
|
|
|
/* inner at full alpha */
|
|
|
|
|
glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->pressure_value, 40);
|
|
|
|
|
/* outer at half alpha */
|
|
|
|
|
glColor4f(outline_col[0], outline_col[1], outline_col[2], outline_alpha * 0.5f);
|
2013-01-16 19:22:15 +00:00
|
|
|
}
|
2012-03-28 03:47:33 +00:00
|
|
|
glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius, 40);
|
2012-01-19 02:06:09 +00:00
|
|
|
glTranslatef(-translation[0], -translation[1], 0);
|
|
|
|
|
|
|
|
|
|
/* restore GL state */
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Public API */
|
|
|
|
|
|
|
|
|
|
void paint_cursor_start(bContext *C, int (*poll)(bContext *C))
|
|
|
|
|
{
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
Paint *p = BKE_paint_get_active_from_context(C);
|
2012-01-19 02:06:09 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (p && !p->paint_cursor)
|
2012-01-19 02:06:09 +00:00
|
|
|
p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL);
|
Paint refactoring commit, non-disruptive (in theory :p)
* Fix precision overflow issue with overlay previews,
* Expose alpha mask mapping to UI (still not functional but coming soon).
* More overlay refactoring:
Overlay now does minimal checking for texture refresh.
Instead, we now have invalidation flags to set an aspect of the brush
overlay as invalid. This is necessary because this way we will be able to
separate and preview different brush attributes on the overlays, using
different textures:
These attributes/aspects are:
Primary texture (main texture for sculpt, vertex, imapaint)
Secondary texture (mask/alpha texture for imapaint)
Cursor texture (cursor texture. It involves brush strength and curves)
Modified the relevant RNA property update functions and C update callback
functions to call the relevant cursor invalidation functions instead
of checking every frame for multiple properties.
Properties that affect this are:
Image changes, if image is used by current brush,
Texture slot changes, similarly
Curve changes,
Object mode change invalidates the cursor
Paint tool change invalidates the cursor.
These changes give slightly more invalidation cases than simply
comparing the relevant properties each frame, but these do not occur in
performance critical moments and it's a much more elegant system than
adding more variables to check per frame each time we add something on
the system.
2013-04-12 17:21:31 +00:00
|
|
|
|
|
|
|
|
/* invalidate the paint cursors */
|
|
|
|
|
BKE_paint_invalidate_overlay_all();
|
2012-01-19 02:06:09 +00:00
|
|
|
}
|
2013-03-29 14:02:28 +00:00
|
|
|
|
|
|
|
|
void paint_cursor_start_explicit(Paint *p, wmWindowManager *wm, int (*poll)(bContext *C))
|
|
|
|
|
{
|
|
|
|
|
if (p && !p->paint_cursor)
|
|
|
|
|
p->paint_cursor = WM_paint_cursor_activate(wm, poll, paint_draw_cursor, NULL);
|
|
|
|
|
}
|