[Bf-blender-cvs] [8e3cefd0d5f] blender2.8: DwM: Object mode empty-image support
Campbell Barton
noreply at git.blender.org
Sat May 20 15:19:55 CEST 2017
Commit: 8e3cefd0d5f9d6ec874012db68f5c4b497af9d35
Author: Campbell Barton
Date: Sat May 20 22:57:47 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB8e3cefd0d5f9d6ec874012db68f5c4b497af9d35
DwM: Object mode empty-image support
===================================================================
M source/blender/draw/CMakeLists.txt
M source/blender/draw/intern/draw_cache.c
M source/blender/draw/intern/draw_cache.h
M source/blender/draw/intern/draw_common.h
M source/blender/draw/modes/object_mode.c
A source/blender/draw/modes/shaders/object_empty_image_frag.glsl
A source/blender/draw/modes/shaders/object_empty_image_vert.glsl
===================================================================
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index ac648fe1e5b..a7432211160 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -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)
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index db1565c8e96..a75b1434721 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -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)
{
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index a37b9998ff6..b440f9969b3 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -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);
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 04c64357cf3..2c597a175ff 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -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);
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index bc1a69fd4ed..89e085423d4 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -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_pla
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list