DwM: Object mode empty-image support
This commit is contained in:
parent
65aab6cdae
commit
8e3cefd0d5
|
@ -154,6 +154,8 @@ data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC)
|
|||
data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_expand_frag.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/object_outline_detect_frag.glsl SRC)
|
||||
|
|
|
@ -53,6 +53,8 @@ static struct DRWShapeCache {
|
|||
Batch *drw_empty_cone;
|
||||
Batch *drw_arrows;
|
||||
Batch *drw_axis_names;
|
||||
Batch *drw_image_plane;
|
||||
Batch *drw_image_plane_wire;
|
||||
Batch *drw_field_wind;
|
||||
Batch *drw_field_force;
|
||||
Batch *drw_field_vortex;
|
||||
|
@ -100,6 +102,8 @@ void DRW_shape_cache_free(void)
|
|||
BATCH_DISCARD_ALL_SAFE(SHC.drw_empty_cone);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_arrows);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_axis_names);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane_wire);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_field_wind);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_field_force);
|
||||
BATCH_DISCARD_ALL_SAFE(SHC.drw_field_vortex);
|
||||
|
@ -723,6 +727,46 @@ Batch *DRW_cache_axis_names_get(void)
|
|||
return SHC.drw_axis_names;
|
||||
}
|
||||
|
||||
Batch *DRW_cache_image_plane_get(void)
|
||||
{
|
||||
if (!SHC.drw_image_plane) {
|
||||
const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
|
||||
static VertexFormat format = { 0 };
|
||||
static struct { uint pos, texCoords; } attr_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
||||
attr_id.texCoords = VertexFormat_add_attrib(&format, "texCoord", COMP_F32, 2, KEEP_FLOAT);
|
||||
}
|
||||
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
|
||||
VertexBuffer_allocate_data(vbo, 4);
|
||||
for (uint j = 0; j < 4; j++) {
|
||||
VertexBuffer_set_attrib(vbo, attr_id.pos, j, quad[j]);
|
||||
VertexBuffer_set_attrib(vbo, attr_id.texCoords, j, quad[j]);
|
||||
}
|
||||
SHC.drw_image_plane = Batch_create(PRIM_TRIANGLE_FAN, vbo, NULL);
|
||||
}
|
||||
return SHC.drw_image_plane;
|
||||
}
|
||||
|
||||
Batch *DRW_cache_image_plane_wire_get(void)
|
||||
{
|
||||
if (!SHC.drw_image_plane_wire) {
|
||||
const float quad[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
|
||||
static VertexFormat format = { 0 };
|
||||
static struct { uint pos; } attr_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
attr_id.pos = VertexFormat_add_attrib(&format, "pos", COMP_F32, 2, KEEP_FLOAT);
|
||||
}
|
||||
VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
|
||||
VertexBuffer_allocate_data(vbo, 4);
|
||||
for (uint j = 0; j < 4; j++) {
|
||||
VertexBuffer_set_attrib(vbo, attr_id.pos, j, quad[j]);
|
||||
}
|
||||
SHC.drw_image_plane_wire = Batch_create(PRIM_LINE_LOOP, vbo, NULL);
|
||||
}
|
||||
return SHC.drw_image_plane_wire;
|
||||
}
|
||||
|
||||
/* Force Field */
|
||||
Batch *DRW_cache_field_wind_get(void)
|
||||
{
|
||||
|
|
|
@ -53,6 +53,8 @@ struct Batch *DRW_cache_empty_sphere_get(void);
|
|||
struct Batch *DRW_cache_empty_cone_get(void);
|
||||
struct Batch *DRW_cache_arrows_get(void);
|
||||
struct Batch *DRW_cache_axis_names_get(void);
|
||||
struct Batch *DRW_cache_image_plane_get(void);
|
||||
struct Batch *DRW_cache_image_plane_wire_get(void);
|
||||
|
||||
/* Force Field */
|
||||
struct Batch *DRW_cache_field_wind_get(void);
|
||||
|
|
|
@ -96,6 +96,7 @@ struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, st
|
|||
struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
|
||||
struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_instance_image_plane(struct DRWPass *pass, struct Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Batch *geom);
|
||||
|
|
|
@ -35,16 +35,20 @@
|
|||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
|
||||
#include "BKE_anim.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
|
@ -60,6 +64,8 @@ extern char datatoc_object_outline_detect_frag_glsl[];
|
|||
extern char datatoc_object_outline_expand_frag_glsl[];
|
||||
extern char datatoc_object_grid_frag_glsl[];
|
||||
extern char datatoc_object_grid_vert_glsl[];
|
||||
extern char datatoc_object_empty_image_frag_glsl[];
|
||||
extern char datatoc_object_empty_image_vert_glsl[];
|
||||
extern char datatoc_particle_prim_vert_glsl[];
|
||||
extern char datatoc_particle_prim_frag_glsl[];
|
||||
extern char datatoc_common_globals_lib_glsl[];
|
||||
|
@ -101,6 +107,13 @@ typedef struct OBJECT_Data {
|
|||
OBJECT_StorageList *stl;
|
||||
} OBJECT_Data;
|
||||
|
||||
/* per-image shading groups for image-type empty objects */
|
||||
struct EmptyImageShadingGroupData {
|
||||
DRWShadingGroup *shgrp_image;
|
||||
DRWShadingGroup *shgrp_wire;
|
||||
float image_aspect[2];
|
||||
};
|
||||
|
||||
/* *********** STATIC *********** */
|
||||
|
||||
typedef struct OBJECT_PrivateData{
|
||||
|
@ -114,6 +127,8 @@ typedef struct OBJECT_PrivateData{
|
|||
DRWShadingGroup *single_arrow_line;
|
||||
DRWShadingGroup *arrows;
|
||||
DRWShadingGroup *axis_names;
|
||||
/* GPUTexture -> EmptyImageShadingGroupData */
|
||||
GHash *image_plane_map;
|
||||
|
||||
/* Force Field */
|
||||
DRWShadingGroup *field_wind;
|
||||
|
@ -187,9 +202,14 @@ typedef struct OBJECT_PrivateData{
|
|||
} OBJECT_PrivateData; /* Transient data */
|
||||
|
||||
static struct {
|
||||
/* fullscreen shaders */
|
||||
GPUShader *outline_resolve_sh;
|
||||
GPUShader *outline_detect_sh;
|
||||
GPUShader *outline_fade_sh;
|
||||
|
||||
/* regular shaders */
|
||||
GPUShader *object_empty_image_sh;
|
||||
GPUShader *object_empty_image_wire_sh;
|
||||
GPUShader *grid_sh;
|
||||
GPUShader *part_dot_sh;
|
||||
GPUShader *part_prim_sh;
|
||||
|
@ -256,6 +276,21 @@ static void OBJECT_engine_init(void *vedata)
|
|||
e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
|
||||
}
|
||||
|
||||
if (!e_data.object_empty_image_sh) {
|
||||
e_data.object_empty_image_sh = DRW_shader_create_with_lib(
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl,
|
||||
datatoc_common_globals_lib_glsl, NULL);
|
||||
}
|
||||
|
||||
if (!e_data.object_empty_image_wire_sh) {
|
||||
e_data.object_empty_image_wire_sh = DRW_shader_create_with_lib(
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl,
|
||||
datatoc_common_globals_lib_glsl,
|
||||
"#define USE_WIRE\n");
|
||||
}
|
||||
|
||||
if (!e_data.grid_sh) {
|
||||
e_data.grid_sh = DRW_shader_create_with_lib(
|
||||
datatoc_object_grid_vert_glsl, NULL,
|
||||
|
@ -412,6 +447,8 @@ static void OBJECT_engine_free(void)
|
|||
DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.outline_fade_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.object_empty_image_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.grid_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.part_prim_sh);
|
||||
}
|
||||
|
@ -467,6 +504,118 @@ static DRWShadingGroup *shgroup_theme_id_to_wire_or(
|
|||
}
|
||||
}
|
||||
|
||||
static void image_calc_aspect(Image *ima, ImageUser *iuser, float r_image_aspect[2])
|
||||
{
|
||||
float ima_x, ima_y;
|
||||
if (ima) {
|
||||
int w, h;
|
||||
BKE_image_get_size(ima, iuser, &w, &h);
|
||||
ima_x = w;
|
||||
ima_y = h;
|
||||
}
|
||||
else {
|
||||
/* if no image, make it a 1x1 empty square, honor scale & offset */
|
||||
ima_x = ima_y = 1.0f;
|
||||
}
|
||||
/* Get the image aspect even if the buffer is invalid */
|
||||
float sca_x = 1.0f, sca_y = 1.0f;
|
||||
if (ima) {
|
||||
if (ima->aspx > ima->aspy) {
|
||||
sca_y = ima->aspy / ima->aspx;
|
||||
}
|
||||
else if (ima->aspx < ima->aspy) {
|
||||
sca_x = ima->aspx / ima->aspy;
|
||||
}
|
||||
}
|
||||
|
||||
const float scale_x_inv = ima_x * sca_x;
|
||||
const float scale_y_inv = ima_y * sca_y;
|
||||
if (scale_x_inv > scale_y_inv) {
|
||||
r_image_aspect[0] = 1.0f;
|
||||
r_image_aspect[1] = scale_y_inv / scale_x_inv;
|
||||
}
|
||||
else {
|
||||
r_image_aspect[0] = scale_x_inv / scale_y_inv;
|
||||
r_image_aspect[1] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void DRW_shgroup_empty_image(
|
||||
OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, float color[4])
|
||||
{
|
||||
/* TODO: 'StereoViews', see draw_empty_image. */
|
||||
|
||||
if (stl->g_data->image_plane_map == NULL) {
|
||||
stl->g_data->image_plane_map = BLI_ghash_ptr_new(__func__);
|
||||
}
|
||||
|
||||
struct EmptyImageShadingGroupData *empty_image_data;
|
||||
|
||||
GPUTexture *tex = ob->data ?
|
||||
GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, false, false) : NULL;
|
||||
void **val_p;
|
||||
|
||||
/* Create on demand, 'tex' may be NULL. */
|
||||
if (BLI_ghash_ensure_p(stl->g_data->image_plane_map, tex, &val_p)) {
|
||||
empty_image_data = *val_p;
|
||||
}
|
||||
else {
|
||||
empty_image_data = MEM_mallocN(sizeof(*empty_image_data), __func__);
|
||||
|
||||
image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect);
|
||||
|
||||
if (tex) {
|
||||
struct Batch *geom = DRW_cache_image_plane_get();
|
||||
DRWShadingGroup *grp = DRW_shgroup_instance_create(
|
||||
e_data.object_empty_image_sh, psl->non_meshes, geom);
|
||||
DRW_shgroup_attrib_float(grp, "objectColor", 4);
|
||||
DRW_shgroup_attrib_float(grp, "size", 1);
|
||||
DRW_shgroup_attrib_float(grp, "offset", 2);
|
||||
DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
|
||||
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
|
||||
|
||||
empty_image_data->shgrp_image = grp;
|
||||
}
|
||||
else {
|
||||
empty_image_data->shgrp_image = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
struct Batch *geom = DRW_cache_image_plane_wire_get();
|
||||
DRWShadingGroup *grp = DRW_shgroup_instance_create(
|
||||
e_data.object_empty_image_wire_sh, psl->non_meshes, geom);
|
||||
DRW_shgroup_attrib_float(grp, "color", 3);
|
||||
DRW_shgroup_attrib_float(grp, "size", 1);
|
||||
DRW_shgroup_attrib_float(grp, "offset", 2);
|
||||
DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
|
||||
|
||||
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
|
||||
|
||||
empty_image_data->shgrp_wire = grp;
|
||||
}
|
||||
|
||||
*val_p = empty_image_data;
|
||||
}
|
||||
|
||||
if (empty_image_data->shgrp_image != NULL) {
|
||||
DRW_shgroup_call_dynamic_add(
|
||||
empty_image_data->shgrp_image,
|
||||
ob->col,
|
||||
&ob->empty_drawsize,
|
||||
ob->ima_ofs,
|
||||
ob->obmat);
|
||||
}
|
||||
|
||||
DRW_shgroup_call_dynamic_add(
|
||||
empty_image_data->shgrp_wire,
|
||||
color,
|
||||
&ob->empty_drawsize,
|
||||
ob->ima_ofs,
|
||||
ob->obmat);
|
||||
}
|
||||
|
||||
static void OBJECT_cache_init(void *vedata)
|
||||
{
|
||||
OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
|
||||
|
@ -668,6 +817,9 @@ static void OBJECT_cache_init(void *vedata)
|
|||
geom = DRW_cache_axis_names_get();
|
||||
stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
|
||||
|
||||
/* initialize on first use */
|
||||
stl->g_data->image_plane_map = NULL;
|
||||
|
||||
/* Force Field */
|
||||
geom = DRW_cache_field_wind_get();
|
||||
stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom);
|
||||
|
@ -1054,7 +1206,7 @@ static void DRW_shgroup_camera(OBJECT_StorageList *stl, Object *ob, SceneLayer *
|
|||
}
|
||||
}
|
||||
|
||||
static void DRW_shgroup_empty(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
|
||||
static void DRW_shgroup_empty(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, SceneLayer *sl)
|
||||
{
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, sl, &color);
|
||||
|
@ -1083,6 +1235,9 @@ static void DRW_shgroup_empty(OBJECT_StorageList *stl, Object *ob, SceneLayer *s
|
|||
DRW_shgroup_call_dynamic_add(stl->g_data->arrows, color, &ob->empty_drawsize, ob->obmat);
|
||||
DRW_shgroup_call_dynamic_add(stl->g_data->axis_names, color, &ob->empty_drawsize, ob->obmat);
|
||||
break;
|
||||
case OB_EMPTY_IMAGE:
|
||||
DRW_shgroup_empty_image(stl, psl, ob, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1351,7 +1506,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
DRW_shgroup_camera(stl, ob, sl);
|
||||
break;
|
||||
case OB_EMPTY:
|
||||
DRW_shgroup_empty(stl, ob, sl);
|
||||
DRW_shgroup_empty(stl, psl, ob, sl);
|
||||
break;
|
||||
case OB_SPEAKER:
|
||||
DRW_shgroup_speaker(stl, ob, sl);
|
||||
|
@ -1398,6 +1553,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
}
|
||||
|
||||
static void OBJECT_cache_finish(void *vedata)
|
||||
{
|
||||
OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
|
||||
if (stl->g_data->image_plane_map) {
|
||||
BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN);
|
||||
}
|
||||
}
|
||||
|
||||
static void OBJECT_draw_scene(void *vedata)
|
||||
{
|
||||
|
||||
|
@ -1486,7 +1649,7 @@ DrawEngineType draw_engine_object_type = {
|
|||
&OBJECT_engine_free,
|
||||
&OBJECT_cache_init,
|
||||
&OBJECT_cache_populate,
|
||||
NULL,
|
||||
&OBJECT_cache_finish,
|
||||
NULL,
|
||||
&OBJECT_draw_scene
|
||||
};
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
flat in vec4 finalColor;
|
||||
|
||||
#ifndef USE_WIRE
|
||||
in vec2 texCoord_interp;
|
||||
#endif
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
#ifndef USE_WIRE
|
||||
uniform sampler2D image;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef USE_WIRE
|
||||
fragColor = finalColor;
|
||||
#else
|
||||
fragColor = finalColor * texture(image, texCoord_interp);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform vec2 aspect;
|
||||
|
||||
/* ---- Instanciated Attribs ---- */
|
||||
in vec2 texCoord;
|
||||
in vec2 pos;
|
||||
/* ---- Per instance Attribs ---- */
|
||||
in mat4 InstanceModelMatrix;
|
||||
|
||||
#ifdef USE_WIRE
|
||||
in vec3 color;
|
||||
#else
|
||||
in vec4 objectColor;
|
||||
#endif
|
||||
|
||||
in float size;
|
||||
in vec2 offset;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
#ifndef USE_WIRE
|
||||
out vec2 texCoord_interp;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(
|
||||
(pos[0] + offset[0]) * (size * aspect[0]),
|
||||
(pos[1] + offset[1]) * (size * aspect[1]),
|
||||
0.0, 1.0);
|
||||
#ifdef USE_WIRE
|
||||
finalColor = vec4(color, 1.0);
|
||||
#else
|
||||
texCoord_interp = texCoord;
|
||||
finalColor = objectColor;
|
||||
#endif
|
||||
}
|
Loading…
Reference in New Issue