[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