[Bf-blender-cvs] [976c0cd] strand_gpu: Vertex attributes for the strand root points.

Lukas Tönne noreply at git.blender.org
Tue Jul 5 09:57:10 CEST 2016


Commit: 976c0cd42d1b96b858771b93d82a71bf2b591317
Author: Lukas Tönne
Date:   Sat Jul 2 10:32:04 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB976c0cd42d1b96b858771b93d82a71bf2b591317

Vertex attributes for the strand root points.

These attributes carry information for interpolating guide strands
in the geometry shader. Each strand can have up to 4 guide strands
(identified by index) with a normalized weight for each.

===================================================================

M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/strands.c
M	source/blender/editors/space_view3d/drawstrands.c
M	source/blender/gpu/GPU_strands.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_strands.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index 79005cf..d1d46e1 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -69,7 +69,7 @@ typedef struct StrandRootData {
 	/* Indices of control strands for interpolation */
 	unsigned int control_index[4];
 	/* Weights of control strands for interpolation */
-	float control_weights[4];
+	float control_weight[4];
 } StrandRootData;
 
 typedef struct StrandData {
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index 4ad4616..cd55968 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -124,7 +124,7 @@ StrandData *BKE_strand_data_calc(Strands *strands, DerivedMesh *scalp,
 		int k;
 		for (k = 0; k < 4; ++k) {
 			root->control_index[k] = sroot->control_index[k];
-			root->control_weights[k] = sroot->control_weights[k];
+			root->control_weight[k] = sroot->control_weights[k];
 		}
 	}
 	
diff --git a/source/blender/editors/space_view3d/drawstrands.c b/source/blender/editors/space_view3d/drawstrands.c
index ecb810e..ca07efa 100644
--- a/source/blender/editors/space_view3d/drawstrands.c
+++ b/source/blender/editors/space_view3d/drawstrands.c
@@ -74,7 +74,16 @@ void draw_strands(Strands *strands, StrandData *data, Object *ob, RegionView3D *
 		GPU_strands_setup_roots(data);
 		GPUDrawStrands *gds = data->gpu_buffer;
 		if (gds->root_points) {
-			glDrawArrays(GL_POINTS, 0, gds->totroots * 3);
+			struct GPUAttrib *attrib;
+			int num_attrib;
+			GPU_strand_shader_get_attributes(strands->gpu_shader, &attrib, &num_attrib);
+			
+			int elemsize = GPU_attrib_element_size(attrib, num_attrib);
+			GPU_interleaved_attrib_setup(gds->root_points, attrib, num_attrib, elemsize);
+			
+			glDrawArrays(GL_POINTS, 0, gds->totroots * elemsize);
+			
+			GPU_interleaved_attrib_unbind();
 		}
 		GPU_strands_buffer_unbind();
 		
diff --git a/source/blender/gpu/GPU_strands.h b/source/blender/gpu/GPU_strands.h
index c3a58d3..3ffc30c 100644
--- a/source/blender/gpu/GPU_strands.h
+++ b/source/blender/gpu/GPU_strands.h
@@ -36,6 +36,8 @@
 extern "C" {
 #endif
 
+struct GPUAttrib;
+
 struct Strands;
 
 typedef struct GPUStrandsShader GPUStrandsShader;
@@ -53,6 +55,9 @@ void GPU_strand_shader_bind_uniforms(
 void GPU_strand_shader_unbind(GPUStrandsShader *gpu_shader);
 bool GPU_strand_shader_bound(GPUStrandsShader *gpu_shader);
 
+void GPU_strand_shader_get_attributes(struct GPUStrandsShader *gpu_shader,
+                                      struct GPUAttrib **r_attrib, int *r_num);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 8656e3b..abe59d2 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -2095,6 +2095,12 @@ void GPU_end_draw_pbvh_BB(void)
 /* *************** */
 /* Strands Buffers */
 
+typedef struct RootVertex {
+	float co[3];
+	unsigned int guide_index[4];
+	float guide_weight[4];
+} RootVertex;
+
 typedef enum GPUStrandBufferType {
 	GPU_STRAND_BUFFER_CONTROL_VERTEX = 0,
 	GPU_STRAND_BUFFER_CONTROL_EDGE,
@@ -2141,7 +2147,7 @@ static GPUBufferTexture *gpu_strands_buffer_texture_from_type(GPUDrawStrands *gd
 /* get the amount of space to allocate for a buffer of a particular type */
 static size_t gpu_strands_buffer_size_from_type(StrandData *strands, GPUStrandBufferType type)
 {
-	const int components = gpu_buffer_type_settings[type].num_components;
+	const int components = gpu_strand_buffer_type_settings[type].num_components;
 	const int totverts = strands->gpu_buffer->totverts;
 	const int totcurves = strands->gpu_buffer->totcurves;
 	const int totroots = strands->gpu_buffer->totroots;
@@ -2152,7 +2158,7 @@ static size_t gpu_strands_buffer_size_from_type(StrandData *strands, GPUStrandBu
 		case GPU_STRAND_BUFFER_CONTROL_EDGE:
 			return sizeof(int) * components * (totverts - totcurves);
 		case GPU_STRAND_BUFFER_ROOT_VERTEX:
-			return sizeof(float) * components * totroots;
+			return sizeof(RootVertex) * totroots;
 		default:
 			return -1;
 	}
@@ -2197,14 +2203,19 @@ static void strands_copy_edge_buffer(StrandData *strands, unsigned int (*varray)
 	}
 }
 
-static void strands_copy_root_buffer(StrandData *strands, float (*varray)[3])
+static void strands_copy_root_buffer(StrandData *strands, RootVertex *varray)
 {
 	int totroots = strands->totroots, v;
 	
 	/* strand root points */
 	StrandRootData *root = strands->roots;
 	for (v = 0; v < totroots; ++v, ++root) {
-		copy_v3_v3(*varray++, root->co);
+		copy_v3_v3(varray->co, root->co);
+		for (int k = 0; k < 4; ++k) {
+			varray->guide_index[k] = root->control_index[k];
+			varray->guide_weight[k] = root->control_weight[k];
+		}
+		++varray;
 	}
 }
 
@@ -2218,7 +2229,7 @@ static void strands_copy_gpu_data(StrandData *strands, GPUStrandBufferType type,
 			strands_copy_edge_buffer(strands, (unsigned int (*)[2])varray);
 			break;
 		case GPU_STRAND_BUFFER_ROOT_VERTEX:
-			strands_copy_root_buffer(strands, (float (*)[3])varray);
+			strands_copy_root_buffer(strands, (RootVertex *)varray);
 			break;
 	}
 }
@@ -2349,7 +2360,7 @@ void GPU_strands_setup_roots(StrandData *strands)
 
 	glEnableClientState(GL_VERTEX_ARRAY);
 	glBindBuffer(GL_ARRAY_BUFFER, strands->gpu_buffer->root_points->id);
-	glVertexPointer(3, GL_FLOAT, 0, NULL);
+	glVertexPointer(3, GL_FLOAT, sizeof(RootVertex), NULL);
 
 	GLStates |= (GPU_BUFFER_VERTEX_STATE);
 
@@ -2361,6 +2372,8 @@ void GPU_strands_setup_roots(StrandData *strands)
 
 void GPU_strands_buffer_unbind(void)
 {
+	GPU_interleaved_attrib_unbind();
+	
 	GPU_buffers_unbind();
 	
 	glActiveTexture(GL_TEXTURE0);
diff --git a/source/blender/gpu/intern/gpu_strands.c b/source/blender/gpu/intern/gpu_strands.c
index bc569b7..db8a05b 100644
--- a/source/blender/gpu/intern/gpu_strands.c
+++ b/source/blender/gpu/intern/gpu_strands.c
@@ -31,6 +31,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "GPU_glew.h"
+
 #include "BLI_dynstr.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
@@ -38,16 +40,27 @@
 
 #include "DNA_strand_types.h"
 
+#include "BKE_DerivedMesh.h" /* XXX just because GPU_buffers.h needs a type from here */
 #include "BKE_strands.h"
 
+#include "GPU_buffers.h" /* XXX just for GPUAttrib, can that type be moved? */
 #include "GPU_extensions.h"
 #include "GPU_strands.h"
 #include "GPU_shader.h"
 
+typedef enum GPUStrandAttributes {
+	GPU_STRAND_ATTRIB_POSITION,
+	GPU_STRAND_ATTRIB_GUIDE_INDEX,
+	GPU_STRAND_ATTRIB_GUIDE_WEIGHT,
+	
+	NUM_GPU_STRAND_ATTRIB /* must be last */
+} GPUStrandAttributes;
+
 struct GPUStrandsShader {
 	bool bound;
 	
 	GPUShader *shader;
+	GPUAttrib attributes[NUM_GPU_STRAND_ATTRIB];
 	
 	char *fragmentcode;
 	char *geometrycode;
@@ -55,9 +68,12 @@ struct GPUStrandsShader {
 };
 
 const char *vertex_shader = STRINGIFY(
+	in uvec4 guide_index;
+	in vec4 guide_weight;
+	
 	void main()
 	{
-		vec4 co = gl_ModelViewMatrix * gl_Vertex;
+		vec4 co = gl_ModelViewMatrix * (gl_Vertex + vec4(guide_weight.xyz, 0.0));
 		gl_Position = gl_ProjectionMatrix * co;
 	}
 );
@@ -166,6 +182,26 @@ GPUStrandsShader *GPU_strand_shader_get(struct Strands *strands)
 		gpu_shader->vertexcode = vertexcode;
 		gpu_shader->fragmentcode = fragmentcode;
 		gpu_shader->geometrycode = geometrycode;
+		
+		GPUAttrib *attr;
+		
+		attr = &gpu_shader->attributes[GPU_STRAND_ATTRIB_POSITION];
+		attr->index = -1; /* no explicit attribute, we use gl_Vertex for this */
+		attr->info_index = -1;
+		attr->type = GL_FLOAT;
+		attr->size = 3;
+		
+		attr = &gpu_shader->attributes[GPU_STRAND_ATTRIB_GUIDE_INDEX];
+		attr->index = GPU_shader_get_attribute(gpu_shader->shader, "guide_index");
+		attr->info_index = -1;
+		attr->type = GL_UNSIGNED_INT;
+		attr->size = 4;
+		
+		attr = &gpu_shader->attributes[GPU_STRAND_ATTRIB_GUIDE_WEIGHT];
+		attr->index = GPU_shader_get_attribute(gpu_shader->shader, "guide_weight");
+		attr->info_index = -1;
+		attr->type = GL_FLOAT;
+		attr->size = 4;
 	}
 	else {
 		if (vertexcode)
@@ -202,7 +238,7 @@ void GPU_strand_shader_bind(GPUStrandsShader *gpu_shader,
 		return;
 
 	GPU_shader_bind(gpu_shader->shader);
-	
+
 	UNUSED_VARS(viewmat, viewinv);
 }
 
@@ -225,3 +261,10 @@ bool GPU_strand_shader_bound(GPUStrandsShader *gpu_shader)
 {
 	return gpu_shader->bound;
 }
+
+void GPU_strand_shader_get_attributes(GPUStrandsShader *gpu_shader,
+                                      GPUAttrib **r_attrib, int *r_num)
+{
+	if (r_attrib) *r_attrib = gpu_shader->attributes;
+	if (r_num) *r_num = NUM_GPU_STRAND_ATTRIB;
+}




More information about the Bf-blender-cvs mailing list