Matcap support in 3D Viewport.
Full log is here: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.66/Usability#Matcap_in_3D_viewport Implementation notes: - Matcaps are an extension of Solid draw mode, and don't show in other drawmodes. (It's mostly intended to aid modeling/sculpt) - By design, Matcaps are a UI feature, and only stored locally for the UI itself, and won't affect rendering or materials. - Currently a set of 16 (GPL licensed) Matcaps have been compiled into Blender. It doesn't take memory or cpu time, until you use it. - Brush Icons and Matcaps use same code now, and only get generated/allocated on actually using it (instead of on startup). - The current set might get new or different images still, based on user feedback. - Matcap images are 512x512 pixels, so each image takes 1 Mb memory. Unused matcaps get freed immediately. The Matcap icon previews (128x128 pixels) stay in memory. - Loading own matcap image files will be added later. That needs design and code work to get it stable and memory-friendly. - The GLSL code uses the ID PreviewImage for matcaps. I tested it using the existing Material previews, which has its limits... especially for textured previews the normal-mapped matcap won't look good.
BIN
release/datafiles/matcaps/mc01.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
release/datafiles/matcaps/mc02.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
release/datafiles/matcaps/mc03.jpg
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
release/datafiles/matcaps/mc04.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
release/datafiles/matcaps/mc05.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
release/datafiles/matcaps/mc06.jpg
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
release/datafiles/matcaps/mc07.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
release/datafiles/matcaps/mc08.jpg
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
release/datafiles/matcaps/mc09.jpg
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
release/datafiles/matcaps/mc10.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
release/datafiles/matcaps/mc11.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
release/datafiles/matcaps/mc12.jpg
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
release/datafiles/matcaps/mc13.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
release/datafiles/matcaps/mc14.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
release/datafiles/matcaps/mc15.jpg
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
release/datafiles/matcaps/mc16.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
@ -2427,7 +2427,10 @@ class VIEW3D_PT_view3d_display(Panel):
|
||||
col.label(text="Shading:")
|
||||
col.prop(gs, "material_mode", text="")
|
||||
col.prop(view, "show_textured_solid")
|
||||
|
||||
if view.viewport_shade == 'SOLID':
|
||||
col.prop(view, "use_matcap")
|
||||
if view.use_matcap:
|
||||
col.template_icon_view(view, "matcap_icon")
|
||||
col.prop(view, "show_backface_culling")
|
||||
|
||||
layout.separator()
|
||||
|
@ -51,6 +51,8 @@
|
||||
|
||||
#include "BLO_sys_types.h" // for intptr_t support
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
static GHash *gIcons = NULL;
|
||||
@ -138,7 +140,10 @@ void BKE_previewimg_freefunc(void *link)
|
||||
MEM_freeN(prv->rect[i]);
|
||||
prv->rect[i] = NULL;
|
||||
}
|
||||
if (prv->gputexture[i])
|
||||
GPU_texture_free(prv->gputexture[i]);
|
||||
}
|
||||
|
||||
MEM_freeN(prv);
|
||||
}
|
||||
}
|
||||
@ -165,6 +170,7 @@ PreviewImage *BKE_previewimg_copy(PreviewImage *prv)
|
||||
else {
|
||||
prv_img->rect[i] = NULL;
|
||||
}
|
||||
prv_img->gputexture[i] = NULL;
|
||||
}
|
||||
}
|
||||
return prv_img;
|
||||
|
@ -1850,8 +1850,8 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
|
||||
if (prv->rect[i]) {
|
||||
prv->rect[i] = newdataadr(fd, prv->rect[i]);
|
||||
}
|
||||
prv->gputexture[i] = NULL;
|
||||
}
|
||||
// prv->gputexture[0] = prv->gputexture[1] = NULL;
|
||||
}
|
||||
|
||||
return prv;
|
||||
@ -5998,6 +5998,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
|
||||
v3d->afterdraw_xray.first = v3d->afterdraw_xray.last = NULL;
|
||||
v3d->afterdraw_xraytransp.first = v3d->afterdraw_xraytransp.last = NULL;
|
||||
v3d->properties_storage = NULL;
|
||||
v3d->defmaterial = NULL;
|
||||
|
||||
/* render can be quite heavy, set to wire on load */
|
||||
if (v3d->drawtype == OB_RENDER)
|
||||
|
@ -81,6 +81,25 @@ if(WITH_BLENDER)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/thumb.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC)
|
||||
|
||||
# matcap
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc01.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc02.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc03.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc04.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc05.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc06.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc07.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc08.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc09.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc10.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc11.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc12.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc13.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc14.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc15.jpg SRC)
|
||||
data_to_c_simple(../../../../release/datafiles/matcaps/mc16.jpg SRC)
|
||||
|
||||
endif()
|
||||
|
||||
data_to_c_simple(../../../../release/datafiles/startup.blend SRC)
|
||||
|
@ -77,6 +77,24 @@ sources.extend((
|
||||
os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "twist.png.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
|
||||
|
||||
os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
|
||||
os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
|
||||
|
||||
))
|
||||
|
||||
env.BlenderLib ( 'bf_editor_datafiles', sources, Split(incs), [], libtype=['core', 'player'], priority=[235, 30] )
|
||||
|
@ -150,6 +150,57 @@ extern char datatoc_twist_png[];
|
||||
extern int datatoc_vertexdraw_png_size;
|
||||
extern char datatoc_vertexdraw_png[];
|
||||
|
||||
/* Matcap files */
|
||||
|
||||
extern int datatoc_mc01_jpg_size;
|
||||
extern char datatoc_mc01_jpg[];
|
||||
|
||||
extern int datatoc_mc02_jpg_size;
|
||||
extern char datatoc_mc02_jpg[];
|
||||
|
||||
extern int datatoc_mc03_jpg_size;
|
||||
extern char datatoc_mc03_jpg[];
|
||||
|
||||
extern int datatoc_mc04_jpg_size;
|
||||
extern char datatoc_mc04_jpg[];
|
||||
|
||||
extern int datatoc_mc05_jpg_size;
|
||||
extern char datatoc_mc05_jpg[];
|
||||
|
||||
extern int datatoc_mc06_jpg_size;
|
||||
extern char datatoc_mc06_jpg[];
|
||||
|
||||
extern int datatoc_mc07_jpg_size;
|
||||
extern char datatoc_mc07_jpg[];
|
||||
|
||||
extern int datatoc_mc08_jpg_size;
|
||||
extern char datatoc_mc08_jpg[];
|
||||
|
||||
extern int datatoc_mc09_jpg_size;
|
||||
extern char datatoc_mc09_jpg[];
|
||||
|
||||
extern int datatoc_mc10_jpg_size;
|
||||
extern char datatoc_mc10_jpg[];
|
||||
|
||||
extern int datatoc_mc11_jpg_size;
|
||||
extern char datatoc_mc11_jpg[];
|
||||
|
||||
extern int datatoc_mc12_jpg_size;
|
||||
extern char datatoc_mc12_jpg[];
|
||||
|
||||
extern int datatoc_mc13_jpg_size;
|
||||
extern char datatoc_mc13_jpg[];
|
||||
|
||||
extern int datatoc_mc14_jpg_size;
|
||||
extern char datatoc_mc14_jpg[];
|
||||
|
||||
extern int datatoc_mc15_jpg_size;
|
||||
extern char datatoc_mc15_jpg[];
|
||||
|
||||
extern int datatoc_mc16_jpg_size;
|
||||
extern char datatoc_mc16_jpg[];
|
||||
|
||||
|
||||
|
||||
#endif /* __ED_DATAFILES_H__ */
|
||||
|
||||
|
@ -990,6 +990,24 @@ DEF_ICON(BRUSH_THUMB)
|
||||
DEF_ICON(BRUSH_ROTATE)
|
||||
DEF_ICON(BRUSH_VERTEXDRAW)
|
||||
|
||||
/* Matcaps */
|
||||
DEF_ICON(MATCAP_01)
|
||||
DEF_ICON(MATCAP_02)
|
||||
DEF_ICON(MATCAP_03)
|
||||
DEF_ICON(MATCAP_04)
|
||||
DEF_ICON(MATCAP_05)
|
||||
DEF_ICON(MATCAP_06)
|
||||
DEF_ICON(MATCAP_07)
|
||||
DEF_ICON(MATCAP_08)
|
||||
DEF_ICON(MATCAP_09)
|
||||
DEF_ICON(MATCAP_10)
|
||||
DEF_ICON(MATCAP_11)
|
||||
DEF_ICON(MATCAP_12)
|
||||
DEF_ICON(MATCAP_13)
|
||||
DEF_ICON(MATCAP_14)
|
||||
DEF_ICON(MATCAP_15)
|
||||
DEF_ICON(MATCAP_16)
|
||||
|
||||
/* vector icons, VICO_ prefix added */
|
||||
DEF_VICO(VIEW3D_VEC)
|
||||
DEF_VICO(EDIT_VEC)
|
||||
|
@ -807,6 +807,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, struct bContext *C, struct Pointe
|
||||
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
|
||||
void uiTemplatePreview(uiLayout *layout, struct ID *id, int show_buttons, struct ID *parent, struct MTex *slot);
|
||||
void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int expand);
|
||||
void uiTemplateIconView(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
|
||||
void uiTemplateHistogram(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
|
||||
void uiTemplateWaveform(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
|
||||
void uiTemplateVectorscope(uiLayout *layout, struct PointerRNA *ptr, const char *propname);
|
||||
|
@ -39,6 +39,7 @@ struct World;
|
||||
struct Tex;
|
||||
struct Lamp;
|
||||
struct Material;
|
||||
struct PreviewImage;
|
||||
struct PointerRNA;
|
||||
|
||||
typedef struct IconFile {
|
||||
@ -76,6 +77,8 @@ void UI_icons_free_drawinfo(void *drawinfo);
|
||||
struct ListBase *UI_iconfile_list(void);
|
||||
int UI_iconfile_get_index(const char *filename);
|
||||
|
||||
struct PreviewImage *UI_icon_to_preview(int icon_id);
|
||||
|
||||
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big);
|
||||
|
||||
#endif /* __UI_INTERFACE_ICONS_H__ */
|
||||
|
@ -75,10 +75,6 @@
|
||||
|
||||
#include "interface_intern.h"
|
||||
|
||||
|
||||
// #define ICON_IMAGE_W 600
|
||||
// #define ICON_IMAGE_H 640
|
||||
|
||||
#define ICON_GRID_COLS 26
|
||||
#define ICON_GRID_ROWS 30
|
||||
|
||||
@ -90,6 +86,8 @@ typedef struct IconImage {
|
||||
int w;
|
||||
int h;
|
||||
unsigned int *rect;
|
||||
unsigned char *datatoc_rect;
|
||||
int datatoc_size;
|
||||
} IconImage;
|
||||
|
||||
typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
|
||||
@ -132,13 +130,12 @@ static IconTexture icongltex = {0, 0, 0, 0.0f, 0.0f};
|
||||
|
||||
/* **************************************************** */
|
||||
|
||||
static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type)
|
||||
|
||||
static DrawInfo *def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int size, int type)
|
||||
{
|
||||
Icon *new_icon = NULL;
|
||||
IconImage *iimg = NULL;
|
||||
DrawInfo *di;
|
||||
int y = 0;
|
||||
int imgsize = 0;
|
||||
|
||||
new_icon = MEM_callocN(sizeof(Icon), "texicon");
|
||||
|
||||
@ -155,17 +152,27 @@ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int
|
||||
di->data.texture.h = size;
|
||||
}
|
||||
else if (type == ICON_TYPE_BUFFER) {
|
||||
iimg = MEM_mallocN(sizeof(IconImage), "icon_img");
|
||||
iimg->rect = MEM_mallocN(size * size * sizeof(unsigned int), "icon_rect");
|
||||
iimg = MEM_callocN(sizeof(IconImage), "icon_img");
|
||||
iimg->w = size;
|
||||
iimg->h = size;
|
||||
|
||||
/* Here we store the rect in the icon - same as before */
|
||||
imgsize = bbuf->x;
|
||||
for (y = 0; y < size; y++) {
|
||||
memcpy(&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int));
|
||||
}
|
||||
/* icon buffers can get initialized runtime now, via datatoc */
|
||||
if (bbuf) {
|
||||
int y, imgsize;
|
||||
|
||||
iimg->rect = MEM_mallocN(size * size * sizeof(unsigned int), "icon_rect");
|
||||
|
||||
/* Here we store the rect in the icon - same as before */
|
||||
if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0)
|
||||
memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int));
|
||||
else {
|
||||
/* this code assumes square images */
|
||||
imgsize = bbuf->x;
|
||||
for (y = 0; y < size; y++) {
|
||||
memcpy(&iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], imgsize * sizeof(int));
|
||||
}
|
||||
}
|
||||
}
|
||||
di->data.buffer.image = iimg;
|
||||
}
|
||||
|
||||
@ -173,6 +180,8 @@ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs, int
|
||||
new_icon->drawinfo = di;
|
||||
|
||||
BKE_icon_set(icon_id, new_icon);
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc)
|
||||
@ -463,21 +472,19 @@ static void vicon_move_down_draw(int x, int y, int w, int h, float UNUSED(alpha)
|
||||
static void init_brush_icons(void)
|
||||
{
|
||||
|
||||
#define INIT_BRUSH_ICON(icon_id, name) \
|
||||
{ \
|
||||
bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_ ##name## _png, \
|
||||
datatoc_ ##name## _png_size, \
|
||||
IB_rect, NULL, "<brush icon>"); \
|
||||
if (bbuf) { \
|
||||
IMB_premultiply_alpha(bbuf); \
|
||||
def_internal_icon(bbuf, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
|
||||
} \
|
||||
IMB_freeImBuf(bbuf); \
|
||||
} (void)0
|
||||
#define INIT_BRUSH_ICON(icon_id, name) \
|
||||
{ \
|
||||
unsigned char *rect = (unsigned char *)datatoc_ ##name## _png; \
|
||||
int size = datatoc_ ##name## _png_size; \
|
||||
DrawInfo *di; \
|
||||
\
|
||||
di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER); \
|
||||
di->data.buffer.image->datatoc_rect = rect; \
|
||||
di->data.buffer.image->datatoc_size = size; \
|
||||
}
|
||||
/* end INIT_BRUSH_ICON */
|
||||
|
||||
ImBuf *bbuf;
|
||||
const int w = 96;
|
||||
const int w = 96; /* warning, brush size hardcoded in C, but it gets scaled */
|
||||
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_ADD, add);
|
||||
INIT_BRUSH_ICON(ICON_BRUSH_BLOB, blob);
|
||||
@ -513,6 +520,60 @@ static void init_brush_icons(void)
|
||||
#undef INIT_BRUSH_ICON
|
||||
}
|
||||
|
||||
static void icon_verify_datatoc(IconImage *iimg)
|
||||
{
|
||||
/* if it has own rect, things are all OK */
|
||||
if (iimg->rect)
|
||||
return;
|
||||
|
||||
if (iimg->datatoc_rect) {
|
||||
ImBuf *bbuf = IMB_ibImageFromMemory(iimg->datatoc_rect,
|
||||
iimg->datatoc_size, IB_rect, NULL, "<matcap icon>");
|
||||
/* w and h were set on initialize */
|
||||
if (bbuf->x != iimg->h && bbuf->y != iimg->w)
|
||||
IMB_scalefastImBuf(bbuf, iimg->w, iimg->h);
|
||||
|
||||
iimg->rect = bbuf->rect;
|
||||
bbuf->rect = NULL;
|
||||
IMB_freeImBuf(bbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_matcap_icons(void)
|
||||
{
|
||||
/* dynamic allocation now, tucking datatoc pointers in DrawInfo */
|
||||
#define INIT_MATCAP_ICON(icon_id, name) \
|
||||
{ \
|
||||
unsigned char *rect = (unsigned char *)datatoc_ ##name## _jpg; \
|
||||
int size = datatoc_ ##name## _jpg_size; \
|
||||
DrawInfo *di; \
|
||||
\
|
||||
di = def_internal_icon(NULL, icon_id, 0, 0, 128, ICON_TYPE_BUFFER); \
|
||||
di->data.buffer.image->datatoc_rect = rect; \
|
||||
di->data.buffer.image->datatoc_size = size; \
|
||||
}
|
||||
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_01, mc01);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_02, mc02);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_03, mc03);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_04, mc04);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_05, mc05);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_06, mc06);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_07, mc07);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_08, mc08);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_09, mc09);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_10, mc10);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_11, mc11);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_12, mc12);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_13, mc13);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_14, mc14);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_15, mc15);
|
||||
INIT_MATCAP_ICON(ICON_MATCAP_16, mc16);
|
||||
|
||||
#undef INIT_MATCAP_ICON
|
||||
|
||||
}
|
||||
|
||||
static void init_internal_icons(void)
|
||||
{
|
||||
// bTheme *btheme = UI_GetTheme();
|
||||
@ -762,7 +823,8 @@ void UI_icons_free_drawinfo(void *drawinfo)
|
||||
if (di) {
|
||||
if (di->type == ICON_TYPE_BUFFER) {
|
||||
if (di->data.buffer.image) {
|
||||
MEM_freeN(di->data.buffer.image->rect);
|
||||
if (di->data.buffer.image->rect)
|
||||
MEM_freeN(di->data.buffer.image->rect);
|
||||
MEM_freeN(di->data.buffer.image);
|
||||
}
|
||||
}
|
||||
@ -842,6 +904,7 @@ void UI_icons_init(int first_dyn_id)
|
||||
BKE_icons_init(first_dyn_id);
|
||||
init_internal_icons();
|
||||
init_brush_icons();
|
||||
init_matcap_icons();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -891,6 +954,34 @@ static void icon_set_image(bContext *C, ID *id, PreviewImage *prv_img, enum eIco
|
||||
prv_img->w[size], prv_img->h[size]);
|
||||
}
|
||||
|
||||
PreviewImage *UI_icon_to_preview(int icon_id)
|
||||
{
|
||||
Icon *icon = BKE_icon_get(icon_id);
|
||||
|
||||
if (icon) {
|
||||
DrawInfo *di = (DrawInfo *)icon->drawinfo;
|
||||
if (di && di->data.buffer.image) {
|
||||
ImBuf *bbuf;
|
||||
|
||||
bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size, IB_rect, NULL, "<matcap buffer>");
|
||||
if (bbuf) {
|
||||
PreviewImage *prv = BKE_previewimg_create();
|
||||
|
||||
prv->rect[0] = bbuf->rect;
|
||||
|
||||
prv->w[0] = bbuf->x;
|
||||
prv->h[0] = bbuf->y;
|
||||
|
||||
bbuf->rect = NULL;
|
||||
IMB_freeImBuf(bbuf);
|
||||
|
||||
return prv;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void icon_draw_rect(float x, float y, int w, int h, float UNUSED(aspect), int rw, int rh,
|
||||
unsigned int *rect, float alpha, const float rgb[3], short is_preview)
|
||||
{
|
||||
@ -994,6 +1085,8 @@ static int get_draw_size(enum eIconSizes size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void icon_draw_size(float x, float y, int icon_id, float aspect, float alpha, const float rgb[3],
|
||||
enum eIconSizes size, int draw_size, int UNUSED(nocreate), short is_preview)
|
||||
{
|
||||
@ -1042,6 +1135,8 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
|
||||
/* it is a builtin icon */
|
||||
iimg = di->data.buffer.image;
|
||||
|
||||
icon_verify_datatoc(iimg);
|
||||
|
||||
if (!iimg->rect) return; /* something has gone wrong! */
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -1554,6 +1554,88 @@ void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname
|
||||
MEM_freeN(cb);
|
||||
}
|
||||
|
||||
|
||||
/********************* Icon viewer Template ************************/
|
||||
|
||||
/* ID Search browse menu, open */
|
||||
static uiBlock *icon_view_menu(bContext *C, ARegion *ar, void *arg_litem)
|
||||
{
|
||||
static RNAUpdateCb cb;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
int icon;
|
||||
EnumPropertyItem *item;
|
||||
int a, free;
|
||||
|
||||
/* arg_litem is malloced, can be freed by parent button */
|
||||
cb = *((RNAUpdateCb *)arg_litem);
|
||||
|
||||
icon = RNA_property_enum_get(&cb.ptr, cb.prop);
|
||||
|
||||
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
|
||||
uiBlockSetFlag(block, UI_BLOCK_LOOP | UI_BLOCK_REDRAW);
|
||||
|
||||
|
||||
RNA_property_enum_items(C, &cb.ptr, cb.prop, &item, NULL, &free);
|
||||
|
||||
for (a = 0; item[a].identifier; a++) {
|
||||
int x, y;
|
||||
|
||||
x = (a % 8) * UI_UNIT_X * 6;
|
||||
y = (a / 8) * UI_UNIT_X * 6;
|
||||
|
||||
icon = item[a].icon;
|
||||
but = uiDefIconButR_prop(block, ROW, 0, icon, x, y, UI_UNIT_X * 6, UI_UNIT_Y * 6, &cb.ptr, cb.prop, -1, 0, icon, -1, -1, NULL);
|
||||
uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
|
||||
}
|
||||
|
||||
uiBoundsBlock(block, 0.3f * U.widget_unit);
|
||||
uiBlockSetDirection(block, UI_TOP);
|
||||
uiEndBlock(C, block);
|
||||
|
||||
if (free) {
|
||||
MEM_freeN(item);
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
void uiTemplateIconView(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
||||
RNAUpdateCb *cb;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
rctf rect;
|
||||
int icon;
|
||||
|
||||
if (!prop || RNA_property_type(prop) != PROP_ENUM)
|
||||
return;
|
||||
|
||||
icon = RNA_property_enum_get(ptr, prop);
|
||||
|
||||
cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
|
||||
cb->ptr = *ptr;
|
||||
cb->prop = prop;
|
||||
|
||||
rect.xmin = 0; rect.xmax = 10.0f * UI_UNIT_X;
|
||||
rect.ymin = 0; rect.ymax = 10.0f * UI_UNIT_X;
|
||||
|
||||
block = uiLayoutAbsoluteBlock(layout);
|
||||
|
||||
but = uiDefBlockButN(block, icon_view_menu, MEM_dupallocN(cb), "", 0, 0, UI_UNIT_X * 6, UI_UNIT_Y * 6, "");
|
||||
|
||||
|
||||
// but = uiDefIconButR_prop(block, ROW, 0, icon, 0, 0, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect), ptr, prop, -1, 0, icon, -1, -1, NULL);
|
||||
|
||||
but->icon = icon;
|
||||
uiButSetFlag(but, UI_HAS_ICON | UI_ICON_PREVIEW);
|
||||
|
||||
uiButSetNFunc(but, rna_update_cb, MEM_dupallocN(cb), NULL);
|
||||
|
||||
MEM_freeN(cb);
|
||||
}
|
||||
|
||||
/********************* Histogram Template ************************/
|
||||
|
||||
void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include "ED_types.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
#include "UI_interface_icons.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "BLF_api.h"
|
||||
@ -175,8 +176,9 @@ static int check_object_draw_texture(Scene *scene, View3D *v3d, int drawtype)
|
||||
return TRUE;
|
||||
|
||||
/* textured solid */
|
||||
if (v3d->drawtype == OB_SOLID && (v3d->flag2 & V3D_SOLID_TEX) && !BKE_scene_use_new_shading_nodes(scene))
|
||||
return TRUE;
|
||||
if (v3d->drawtype == OB_SOLID && (v3d->flag2 & (V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP))
|
||||
&& !BKE_scene_use_new_shading_nodes(scene))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -219,6 +221,9 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
|
||||
if (BKE_scene_use_new_shading_nodes(scene))
|
||||
return 0;
|
||||
|
||||
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
|
||||
return 1;
|
||||
|
||||
return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
|
||||
}
|
||||
|
||||
@ -6224,6 +6229,34 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
|
||||
r_ob_wire_col[3] = 255;
|
||||
}
|
||||
|
||||
static void draw_object_matcap_check(Scene *scene, View3D *v3d, Object *ob)
|
||||
{
|
||||
/* fixed rule, active object draws as matcap */
|
||||
if (ob == OBACT) {
|
||||
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
|
||||
return;
|
||||
|
||||
if (v3d->defmaterial == NULL) {
|
||||
extern Material defmaterial;
|
||||
|
||||
v3d->defmaterial = MEM_mallocN(sizeof(Material), "matcap material");
|
||||
*(v3d->defmaterial) = defmaterial;
|
||||
v3d->defmaterial->gpumaterial.first = v3d->defmaterial->gpumaterial.last = NULL;
|
||||
v3d->defmaterial->preview = NULL;
|
||||
}
|
||||
/* first time users */
|
||||
if (v3d->matcap_icon == 0)
|
||||
v3d->matcap_icon = ICON_MATCAP_01;
|
||||
|
||||
if (v3d->defmaterial->preview == NULL)
|
||||
v3d->defmaterial->preview = UI_icon_to_preview(v3d->matcap_icon);
|
||||
|
||||
/* signal to all material checks, gets cleared below */
|
||||
v3d->flag2 |= V3D_SHOW_SOLID_MATCAP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* main object drawing function, draws in selection
|
||||
* \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
|
||||
@ -6314,6 +6347,10 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
|
||||
if (v3d->zbuf == 0 && dt > OB_WIRE) dt = OB_WIRE;
|
||||
dtx = 0;
|
||||
|
||||
/* matcap check */
|
||||
if (dt == OB_SOLID && (v3d->flag2 & V3D_SOLID_MATCAP))
|
||||
draw_object_matcap_check(scene, v3d, ob);
|
||||
|
||||
/* faceselect exception: also draw solid when (dt == wire), except in editmode */
|
||||
if (is_obact && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
|
||||
if (ob->type == OB_MESH) {
|
||||
@ -6813,6 +6850,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
|
||||
/* return warning, this is cached text draw */
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
view3d_cached_text_draw_end(v3d, ar, 1, NULL);
|
||||
/* return warning, clear temp flag */
|
||||
v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
|
||||
|
||||
glLoadMatrixf(rv3d->viewmat);
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
@ -42,16 +43,18 @@
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_object.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "GPU_material.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@ -335,6 +338,14 @@ static void view3d_free(SpaceLink *sl)
|
||||
if (vd->localvd) MEM_freeN(vd->localvd);
|
||||
|
||||
if (vd->properties_storage) MEM_freeN(vd->properties_storage);
|
||||
|
||||
/* matcap material, its preview rect gets freed via icons */
|
||||
if (vd->defmaterial) {
|
||||
if (vd->defmaterial->gpumaterial.first)
|
||||
GPU_material_free(vd->defmaterial);
|
||||
BKE_previewimg_free(&vd->defmaterial->preview);
|
||||
MEM_freeN(vd->defmaterial);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -365,6 +376,8 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl)
|
||||
|
||||
/* copy or clear inside new stuff */
|
||||
|
||||
v3dn->defmaterial = NULL;
|
||||
|
||||
BLI_duplicatelist(&v3dn->bgpicbase, &v3do->bgpicbase);
|
||||
|
||||
v3dn->properties_storage = NULL;
|
||||
|
@ -38,6 +38,7 @@ extern "C" {
|
||||
|
||||
struct Image;
|
||||
struct ImageUser;
|
||||
struct PreviewImage;
|
||||
|
||||
struct GPUTexture;
|
||||
typedef struct GPUTexture GPUTexture;
|
||||
@ -112,6 +113,8 @@ GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]);
|
||||
GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]);
|
||||
GPUTexture *GPU_texture_from_blender(struct Image *ima,
|
||||
struct ImageUser *iuser, int isdata, double time, int mipmap);
|
||||
GPUTexture *GPU_texture_from_preview(struct PreviewImage *prv, int mipmap);
|
||||
|
||||
void GPU_texture_free(GPUTexture *tex);
|
||||
|
||||
void GPU_texture_ref(GPUTexture *tex);
|
||||
|
@ -54,6 +54,7 @@ struct GPUNodeStack;
|
||||
struct GPUMaterial;
|
||||
struct GPUTexture;
|
||||
struct GPULamp;
|
||||
struct PreviewImage;
|
||||
|
||||
typedef struct GPUNode GPUNode;
|
||||
typedef struct GPUNodeLink GPUNodeLink;
|
||||
@ -108,6 +109,7 @@ GPUNodeLink *GPU_attribute(int type, const char *name);
|
||||
GPUNodeLink *GPU_uniform(float *num);
|
||||
GPUNodeLink *GPU_dynamic_uniform(float *num, int dynamictype, void *data);
|
||||
GPUNodeLink *GPU_image(struct Image *ima, struct ImageUser *iuser, int isdata);
|
||||
GPUNodeLink *GPU_image_preview(struct PreviewImage *prv);
|
||||
GPUNodeLink *GPU_texture(int size, float *pixels);
|
||||
GPUNodeLink *GPU_dynamic_texture(struct GPUTexture *tex, int dynamictype, void *data);
|
||||
GPUNodeLink *GPU_builtin(GPUBuiltin builtin);
|
||||
@ -122,6 +124,7 @@ GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
|
||||
/* High level functions to create and use GPU materials */
|
||||
|
||||
GPUMaterial *GPU_material_from_blender(struct Scene *scene, struct Material *ma);
|
||||
GPUMaterial *GPU_material_matcap(struct Scene *scene, struct Material *ma);
|
||||
void GPU_material_free(struct Material *ma);
|
||||
|
||||
void GPU_materials_free(void);
|
||||
|
@ -68,6 +68,9 @@ static char *glsl_material_library = NULL;
|
||||
static const char* GPU_DATATYPE_STR[17] = {"", "float", "vec2", "vec3", "vec4",
|
||||
NULL, NULL, NULL, NULL, "mat3", NULL, NULL, NULL, NULL, NULL, NULL, "mat4"};
|
||||
|
||||
#define LINK_IMAGE_BLENDER 1
|
||||
#define LINK_IMAGE_PREVIEW 2
|
||||
|
||||
/* GLSL code parsing for finding function definitions.
|
||||
* These are stored in a hash for lookup when creating a material. */
|
||||
|
||||
@ -339,7 +342,7 @@ static int codegen_input_has_texture(GPUInput *input)
|
||||
{
|
||||
if (input->link)
|
||||
return 0;
|
||||
else if (input->ima)
|
||||
else if (input->ima || input->prv)
|
||||
return 1;
|
||||
else
|
||||
return input->tex != NULL;
|
||||
@ -411,6 +414,17 @@ static void codegen_set_unique_ids(ListBase *nodes)
|
||||
else
|
||||
input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima));
|
||||
}
|
||||
else if (input->prv) {
|
||||
/* input is texture from preview render, assign only one texid per
|
||||
* buffer to avoid sampling the same texture twice */
|
||||
if (!BLI_ghash_haskey(bindhash, input->prv)) {
|
||||
input->texid = texid++;
|
||||
input->bindtex = 1;
|
||||
BLI_ghash_insert(bindhash, input->prv, SET_INT_IN_POINTER(input->texid));
|
||||
}
|
||||
else
|
||||
input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->prv));
|
||||
}
|
||||
else {
|
||||
if (!BLI_ghash_haskey(bindhash, input->tex)) {
|
||||
/* input is user created texture, check tex pointer */
|
||||
@ -718,7 +732,7 @@ static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (input->ima || input->tex)
|
||||
if (input->ima || input->tex || input->prv)
|
||||
BLI_snprintf(input->shadername, sizeof(input->shadername), "samp%d", input->texid);
|
||||
else
|
||||
BLI_snprintf(input->shadername, sizeof(input->shadername), "unf%d", input->id);
|
||||
@ -726,7 +740,7 @@ static void GPU_nodes_extract_dynamic_inputs(GPUPass *pass, ListBase *nodes)
|
||||
/* pass non-dynamic uniforms to opengl */
|
||||
extract = 0;
|
||||
|
||||
if (input->ima || input->tex) {
|
||||
if (input->ima || input->tex || input->prv) {
|
||||
if (input->bindtex)
|
||||
extract = 1;
|
||||
}
|
||||
@ -762,11 +776,14 @@ void GPU_pass_bind(GPUPass *pass, double time, int mipmap)
|
||||
for (input=inputs->first; input; input=input->next) {
|
||||
if (input->ima)
|
||||
input->tex = GPU_texture_from_blender(input->ima, input->iuser, input->image_isdata, time, mipmap);
|
||||
else if (input->prv)
|
||||
input->tex = GPU_texture_from_preview(input->prv, mipmap);
|
||||
|
||||
if (input->tex && input->bindtex) {
|
||||
GPU_texture_bind(input->tex, input->texid);
|
||||
GPU_shader_uniform_texture(shader, input->shaderloc, input->tex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,7 +798,7 @@ void GPU_pass_update_uniforms(GPUPass *pass)
|
||||
|
||||
/* pass dynamic inputs to opengl, others were removed */
|
||||
for (input=inputs->first; input; input=input->next)
|
||||
if (!(input->ima || input->tex))
|
||||
if (!(input->ima || input->tex || input->prv))
|
||||
GPU_shader_uniform_vector(shader, input->shaderloc, input->type, 1,
|
||||
input->dynamicvec);
|
||||
}
|
||||
@ -799,7 +816,7 @@ void GPU_pass_unbind(GPUPass *pass)
|
||||
if (input->tex && input->bindtex)
|
||||
GPU_texture_unbind(input->tex);
|
||||
|
||||
if (input->ima)
|
||||
if (input->ima || input->prv)
|
||||
input->tex = NULL;
|
||||
}
|
||||
|
||||
@ -915,9 +932,13 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, int type)
|
||||
input->type = GPU_VEC4;
|
||||
input->source = GPU_SOURCE_TEX;
|
||||
|
||||
input->ima = link->ptr1;
|
||||
input->iuser = link->ptr2;
|
||||
input->image_isdata = link->image_isdata;
|
||||
if (link->image == LINK_IMAGE_PREVIEW)
|
||||
input->prv = link->ptr1;
|
||||
else {
|
||||
input->ima = link->ptr1;
|
||||
input->iuser = link->ptr2;
|
||||
input->image_isdata = link->image_isdata;
|
||||
}
|
||||
input->textarget = GL_TEXTURE_2D;
|
||||
input->textype = GPU_TEX2D;
|
||||
MEM_freeN(link);
|
||||
@ -1117,7 +1138,7 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
|
||||
{
|
||||
GPUNodeLink *link = GPU_node_link_create(0);
|
||||
|
||||
link->image= 1;
|
||||
link->image= LINK_IMAGE_BLENDER;
|
||||
link->ptr1= ima;
|
||||
link->ptr2= iuser;
|
||||
link->image_isdata= isdata;
|
||||
@ -1125,6 +1146,17 @@ GPUNodeLink *GPU_image(Image *ima, ImageUser *iuser, int isdata)
|
||||
return link;
|
||||
}
|
||||
|
||||
GPUNodeLink *GPU_image_preview(PreviewImage *prv)
|
||||
{
|
||||
GPUNodeLink *link = GPU_node_link_create(0);
|
||||
|
||||
link->image= LINK_IMAGE_PREVIEW;
|
||||
link->ptr1= prv;
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
GPUNodeLink *GPU_texture(int size, float *pixels)
|
||||
{
|
||||
GPUNodeLink *link = GPU_node_link_create(0);
|
||||
|
@ -43,6 +43,7 @@ struct GPUOutput;
|
||||
struct GPUNode;
|
||||
struct GPUVertexAttribs;
|
||||
struct GPUFrameBuffer;
|
||||
struct PreviewImage;
|
||||
|
||||
#define MAX_FUNCTION_NAME 64
|
||||
#define MAX_PARAMETER 32
|
||||
@ -138,6 +139,7 @@ typedef struct GPUInput {
|
||||
|
||||
struct Image *ima; /* image */
|
||||
struct ImageUser *iuser;/* image user */
|
||||
struct PreviewImage *prv; /* preview images & icons */
|
||||
int image_isdata; /* image does not contain color data */
|
||||
float *dynamicvec; /* vector data in case it is dynamic */
|
||||
int dynamictype; /* origin of the dynamic uniform (GPUDynamicType) */
|
||||
|
@ -664,6 +664,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
|
||||
return *bind;
|
||||
}
|
||||
|
||||
/* Image *ima can be NULL */
|
||||
void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
|
||||
{
|
||||
unsigned int *scalerect = NULL;
|
||||
@ -723,7 +724,8 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
|
||||
|
||||
ima->tpageflag |= IMA_MIPMAP_COMPLETE;
|
||||
if (ima)
|
||||
ima->tpageflag |= IMA_MIPMAP_COMPLETE;
|
||||
}
|
||||
|
||||
if (GLEW_EXT_texture_filter_anisotropic)
|
||||
@ -1283,10 +1285,9 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
|
||||
GPUMaterial *gpumat;
|
||||
GPUBlendMode alphablend;
|
||||
int a;
|
||||
|
||||
int gamma = BKE_scene_check_color_management_enabled(scene);
|
||||
|
||||
int new_shading_nodes = BKE_scene_use_new_shading_nodes(scene);
|
||||
int use_matcap = (v3d->flag2 & V3D_SHOW_SOLID_MATCAP); /* assumes v3d->defmaterial->preview is set */
|
||||
|
||||
/* initialize state */
|
||||
memset(&GMS, 0, sizeof(GMS));
|
||||
@ -1298,7 +1299,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
|
||||
|
||||
GMS.gob = ob;
|
||||
GMS.gscene = scene;
|
||||
GMS.totmat= ob->totcol+1; /* materials start from 1, default material is 0 */
|
||||
GMS.totmat= use_matcap? 1 : ob->totcol+1; /* materials start from 1, default material is 0 */
|
||||
GMS.glay= (v3d->localvd)? v3d->localvd->lay: v3d->lay; /* keep lamps visible in local view */
|
||||
GMS.gviewmat= rv3d->viewmat;
|
||||
GMS.gviewinv= rv3d->viewinv;
|
||||
@ -1324,57 +1325,70 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
|
||||
GMS.alphablend= GMS.alphablend_fixed;
|
||||
}
|
||||
|
||||
/* no materials assigned? */
|
||||
if (ob->totcol==0) {
|
||||
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
|
||||
/* viewport material, setup in space_view3d, defaults to matcap using ma->preview now */
|
||||
if (use_matcap) {
|
||||
GMS.gmatbuf[0] = v3d->defmaterial;
|
||||
GPU_material_matcap(scene, v3d->defmaterial);
|
||||
|
||||
/* do material 1 too, for displists! */
|
||||
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
|
||||
|
||||
if (glsl) {
|
||||
GMS.gmatbuf[0]= &defmaterial;
|
||||
GPU_material_from_blender(GMS.gscene, &defmaterial);
|
||||
}
|
||||
|
||||
GMS.alphablend[0]= GPU_BLEND_SOLID;
|
||||
}
|
||||
else {
|
||||
|
||||
/* setup materials */
|
||||
for (a=1; a<=ob->totcol; a++) {
|
||||
/* find a suitable material */
|
||||
ma= give_current_material(ob, a);
|
||||
if (!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
|
||||
if (ma==NULL) ma= &defmaterial;
|
||||
/* no materials assigned? */
|
||||
if (ob->totcol==0) {
|
||||
gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
|
||||
|
||||
/* create glsl material if requested */
|
||||
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
|
||||
/* do material 1 too, for displists! */
|
||||
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
|
||||
|
||||
if (gpumat) {
|
||||
/* do glsl only if creating it succeed, else fallback */
|
||||
GMS.gmatbuf[a]= ma;
|
||||
alphablend = GPU_material_alpha_blend(gpumat, ob->col);
|
||||
if (glsl) {
|
||||
GMS.gmatbuf[0]= &defmaterial;
|
||||
GPU_material_from_blender(GMS.gscene, &defmaterial);
|
||||
}
|
||||
|
||||
GMS.alphablend[0]= GPU_BLEND_SOLID;
|
||||
}
|
||||
else {
|
||||
/* fixed function opengl materials */
|
||||
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
|
||||
|
||||
if (GMS.use_alpha_pass) {
|
||||
GMS.matbuf[a].diff[3]= ma->alpha;
|
||||
alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
|
||||
/* setup materials */
|
||||
for (a=1; a<=ob->totcol; a++) {
|
||||
/* find a suitable material */
|
||||
ma= give_current_material(ob, a);
|
||||
if (!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
|
||||
if (ma==NULL) ma= &defmaterial;
|
||||
|
||||
/* create glsl material if requested */
|
||||
gpumat = (glsl)? GPU_material_from_blender(GMS.gscene, ma): NULL;
|
||||
|
||||
if (gpumat) {
|
||||
/* do glsl only if creating it succeed, else fallback */
|
||||
GMS.gmatbuf[a]= ma;
|
||||
alphablend = GPU_material_alpha_blend(gpumat, ob->col);
|
||||
}
|
||||
else {
|
||||
GMS.matbuf[a].diff[3]= 1.0f;
|
||||
alphablend = GPU_BLEND_SOLID;
|
||||
/* fixed function opengl materials */
|
||||
gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
|
||||
|
||||
if (GMS.use_alpha_pass) {
|
||||
GMS.matbuf[a].diff[3]= ma->alpha;
|
||||
alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
|
||||
}
|
||||
else {
|
||||
GMS.matbuf[a].diff[3]= 1.0f;
|
||||
alphablend = GPU_BLEND_SOLID;
|
||||
}
|
||||
}
|
||||
|
||||
/* setting 'do_alpha_after = TRUE' indicates this object needs to be
|
||||
* drawn in a second alpha pass for improved blending */
|
||||
if (do_alpha_after && !GMS.is_alpha_pass)
|
||||
if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
|
||||
*do_alpha_after = TRUE;
|
||||
|
||||
GMS.alphablend[a]= alphablend;
|
||||
}
|
||||
|
||||
/* setting 'do_alpha_after = TRUE' indicates this object needs to be
|
||||
* drawn in a second alpha pass for improved blending */
|
||||
if (do_alpha_after && !GMS.is_alpha_pass)
|
||||
if (ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT))
|
||||
*do_alpha_after = TRUE;
|
||||
|
||||
GMS.alphablend[a]= alphablend;
|
||||
}
|
||||
|
||||
/* let's start with a clean state */
|
||||
|
@ -539,6 +539,7 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, d
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
|
||||
|
||||
GPU_update_image_time(ima, time);
|
||||
/* this binds a texture, so that's why to restore it with lastbindcode */
|
||||
bindcode = GPU_verify_image(ima, iuser, 0, 0, mipmap, isdata);
|
||||
|
||||
if (ima->gputexture) {
|
||||
@ -579,6 +580,59 @@ GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, int isdata, d
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_from_preview(PreviewImage *prv, int mipmap)
|
||||
{
|
||||
GPUTexture *tex = prv->gputexture[0];
|
||||
GLint w, h, lastbindcode;
|
||||
GLuint bindcode = 0;
|
||||
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastbindcode);
|
||||
|
||||
if (tex)
|
||||
bindcode = tex->bindcode;
|
||||
|
||||
/* this binds a texture, so that's why to restore it */
|
||||
if (bindcode == 0) {
|
||||
GPU_create_gl_tex(&bindcode, prv->rect[0], NULL, prv->w[0], prv->h[0], mipmap, 0, NULL);
|
||||
}
|
||||
if (tex) {
|
||||
tex->bindcode = bindcode;
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
return tex;
|
||||
}
|
||||
|
||||
/* error binding anything */
|
||||
if (!bindcode) {
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
|
||||
tex->bindcode = bindcode;
|
||||
tex->number = -1;
|
||||
tex->refcount = 1;
|
||||
tex->target = GL_TEXTURE_2D;
|
||||
|
||||
prv->gputexture[0]= tex;
|
||||
|
||||
if (!glIsTexture(tex->bindcode)) {
|
||||
GPU_print_error("Blender Texture");
|
||||
}
|
||||
else {
|
||||
glBindTexture(GL_TEXTURE_2D, tex->bindcode);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
|
||||
|
||||
tex->w = w;
|
||||
tex->h = h;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, lastbindcode);
|
||||
|
||||
return tex;
|
||||
|
||||
}
|
||||
|
||||
GPUTexture *GPU_texture_create_1D(int w, float *fpixels, char err_out[256])
|
||||
{
|
||||
GPUTexture *tex = GPU_texture_create_nD(w, 1, 1, fpixels, 0, err_out);
|
||||
|
@ -1506,6 +1506,52 @@ static GPUNodeLink *gpu_material_diffuse_bsdf(GPUMaterial *mat, Material *ma)
|
||||
return outlink;
|
||||
}
|
||||
|
||||
static GPUNodeLink *gpu_material_preview_matcap(GPUMaterial *mat, Material *ma)
|
||||
{
|
||||
GPUNodeLink *outlink;
|
||||
|
||||
GPU_link(mat, "material_preview_matcap", GPU_uniform(&ma->r), GPU_image_preview(ma->preview), GPU_builtin(GPU_VIEW_NORMAL), &outlink);
|
||||
|
||||
return outlink;
|
||||
}
|
||||
|
||||
/* new solid draw mode with glsl matcaps */
|
||||
GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma)
|
||||
{
|
||||
GPUMaterial *mat;
|
||||
GPUNodeLink *outlink;
|
||||
LinkData *link;
|
||||
|
||||
for (link=ma->gpumaterial.first; link; link=link->next)
|
||||
if (((GPUMaterial*)link->data)->scene == scene)
|
||||
return link->data;
|
||||
|
||||
/* allocate material */
|
||||
mat = GPU_material_construct_begin(ma);
|
||||
mat->scene = scene;
|
||||
|
||||
if (ma->preview && ma->preview->rect[0]) {
|
||||
outlink = gpu_material_preview_matcap(mat, ma);
|
||||
}
|
||||
else {
|
||||
outlink = gpu_material_diffuse_bsdf(mat, ma);
|
||||
}
|
||||
|
||||
GPU_material_output_link(mat, outlink);
|
||||
|
||||
GPU_material_construct_end(mat);
|
||||
|
||||
/* note that even if building the shader fails in some way, we still keep
|
||||
* it to avoid trying to compile again and again, and simple do not use
|
||||
* the actual shader on drawing */
|
||||
|
||||
link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
|
||||
link->data = mat;
|
||||
BLI_addtail(&ma->gpumaterial, link);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
|
||||
{
|
||||
GPUMaterial *mat;
|
||||
|
@ -2256,3 +2256,18 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
|
||||
result = surface;
|
||||
}
|
||||
|
||||
/* ********************** matcap style render ******************** */
|
||||
|
||||
void material_preview_matcap(vec4 color, sampler2D ima, vec3 N, out vec4 result)
|
||||
{
|
||||
vec2 tex;
|
||||
|
||||
if (N.z < 0.0) {
|
||||
N.z = 0.0;
|
||||
N = normalize(N);
|
||||
}
|
||||
|
||||
tex.x = 0.5 + 0.49 * N.x;
|
||||
tex.y = 0.5 + 0.49 * N.y;
|
||||
result = texture2D(ima, tex);
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ struct Library;
|
||||
struct FileData;
|
||||
struct ID;
|
||||
struct PackedFile;
|
||||
struct GPUTexture;
|
||||
|
||||
typedef struct IDPropertyData {
|
||||
void *pointer;
|
||||
@ -154,6 +155,7 @@ typedef struct PreviewImage {
|
||||
short changed[2];
|
||||
short changed_timestamp[2];
|
||||
unsigned int *rect[2];
|
||||
struct GPUTexture *gputexture[2];
|
||||
} PreviewImage;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +46,7 @@ struct RenderEngine;
|
||||
struct bGPdata;
|
||||
struct SmoothView3DStore;
|
||||
struct wmTimer;
|
||||
struct Material;
|
||||
|
||||
/* This is needed to not let VC choke on near and far... old
|
||||
* proprietary MS extensions... */
|
||||
@ -160,8 +161,8 @@ typedef struct View3D {
|
||||
|
||||
float bundle_size; /* size of bundles in reconstructed data */
|
||||
short bundle_drawtype; /* display style for bundle */
|
||||
|
||||
char pad[6];
|
||||
short pad;
|
||||
int matcap_icon; /* icon id */
|
||||
|
||||
unsigned int lay_used; /* used while drawing */
|
||||
|
||||
@ -209,10 +210,10 @@ typedef struct View3D {
|
||||
|
||||
/* drawflags, denoting state */
|
||||
short zbuf, transp, xray;
|
||||
|
||||
char pad3[2];
|
||||
|
||||
void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
|
||||
void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
|
||||
struct Material *defmaterial; /* used by matcap now */
|
||||
|
||||
/* XXX deprecated? */
|
||||
struct bGPdata *gpd DNA_DEPRECATED; /* Grease-Pencil Data (annotation layers) */
|
||||
@ -264,12 +265,14 @@ typedef struct View3D {
|
||||
#define V3D_SOLID_TEX 8
|
||||
#define V3D_SHOW_GPENCIL 16
|
||||
#define V3D_LOCK_CAMERA 32
|
||||
#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
|
||||
#define V3D_SHOW_RECONSTRUCTION 128
|
||||
#define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */
|
||||
#define V3D_SHOW_RECONSTRUCTION 128
|
||||
#define V3D_SHOW_CAMERAPATH 256
|
||||
#define V3D_SHOW_BUNDLENAME 512
|
||||
#define V3D_BACKFACE_CULLING 1024
|
||||
#define V3D_RENDER_BORDER 2048
|
||||
#define V3D_RENDER_BORDER 2048
|
||||
#define V3D_SOLID_MATCAP 4096 /* user flag */
|
||||
#define V3D_SHOW_SOLID_MATCAP 8192 /* runtime flag */
|
||||
|
||||
/* View3D->around */
|
||||
#define V3D_CENTER 0
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
@ -376,6 +377,24 @@ static void rna_SpaceView3D_viewport_shade_update(Main *UNUSED(bmain), Scene *UN
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
View3D *v3d = (View3D *)(ptr->data);
|
||||
|
||||
if (v3d->defmaterial) {
|
||||
Material *ma = v3d->defmaterial;
|
||||
|
||||
if (ma->preview)
|
||||
BKE_previewimg_free(&ma->preview);
|
||||
|
||||
if (ma->gpumaterial.first)
|
||||
GPU_material_free(ma);
|
||||
|
||||
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void rna_SpaceView3D_pivot_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
if (U.uiflag & USER_LOCKAROUND) {
|
||||
@ -1463,6 +1482,7 @@ static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_function_ui_description(func, "Remove all background images");
|
||||
}
|
||||
|
||||
|
||||
static void rna_def_space_view3d(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -1499,6 +1519,27 @@ static void rna_def_space_view3d(BlenderRNA *brna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem view3d_matcap_items[] = {
|
||||
{ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
|
||||
{ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
|
||||
{ICON_MATCAP_03, "03", ICON_MATCAP_03, "", ""},
|
||||
{ICON_MATCAP_04, "04", ICON_MATCAP_04, "", ""},
|
||||
{ICON_MATCAP_05, "05", ICON_MATCAP_05, "", ""},
|
||||
{ICON_MATCAP_06, "06", ICON_MATCAP_06, "", ""},
|
||||
{ICON_MATCAP_07, "07", ICON_MATCAP_07, "", ""},
|
||||
{ICON_MATCAP_08, "08", ICON_MATCAP_08, "", ""},
|
||||
{ICON_MATCAP_09, "09", ICON_MATCAP_09, "", ""},
|
||||
{ICON_MATCAP_10, "10", ICON_MATCAP_10, "", ""},
|
||||
{ICON_MATCAP_11, "11", ICON_MATCAP_11, "", ""},
|
||||
{ICON_MATCAP_12, "12", ICON_MATCAP_12, "", ""},
|
||||
{ICON_MATCAP_13, "13", ICON_MATCAP_13, "", ""},
|
||||
{ICON_MATCAP_14, "14", ICON_MATCAP_14, "", ""},
|
||||
{ICON_MATCAP_15, "15", ICON_MATCAP_15, "", ""},
|
||||
{ICON_MATCAP_16, "16", ICON_MATCAP_16, "", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
srna = RNA_def_struct(brna, "SpaceView3D", "Space");
|
||||
RNA_def_struct_sdna(srna, "View3D");
|
||||
RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
|
||||
@ -1819,6 +1860,17 @@ static void rna_def_space_view3d(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Show 3D Marker Names", "Show names for reconstructed tracks objects");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_matcap", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_MATCAP);
|
||||
RNA_def_property_ui_text(prop, "Matcap", "Active Objects draw images mapped on normals, enhancing Solid Draw Mode");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "matcap_icon");
|
||||
RNA_def_property_enum_items(prop, view3d_matcap_items);
|
||||
RNA_def_property_ui_text(prop, "Matcap", "Image to use for Material Capture, active objects only");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_update");
|
||||
|
||||
/* region */
|
||||
|
||||
srna = RNA_def_struct(brna, "RegionView3D", NULL);
|
||||
|
@ -512,6 +512,10 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
api_ui_item_rna_common(func);
|
||||
RNA_def_boolean(func, "expand", 0, "", "Expand button to show more detail");
|
||||
|
||||
func = RNA_def_function(srna, "template_icon_view", "uiTemplateIconView");
|
||||
RNA_def_function_ui_description(func, "Enum. Large widget showing Icon previews");
|
||||
api_ui_item_rna_common(func);
|
||||
|
||||
func = RNA_def_function(srna, "template_histogram", "uiTemplateHistogram");
|
||||
RNA_def_function_ui_description(func, "Item. A histogramm widget to analyze imaga data");
|
||||
api_ui_item_rna_common(func);
|
||||
|