[Bf-blender-cvs] [27674ca] hair_system: Buffered render hair drawing.

Lukas Tönne noreply at git.blender.org
Mon Aug 11 18:08:02 CEST 2014


Commit: 27674ca84b654f7a856f9304ed3df9b2326d9082
Author: Lukas Tönne
Date:   Mon Aug 11 17:08:40 2014 +0200
Branches: hair_system
https://developer.blender.org/rB27674ca84b654f7a856f9304ed3df9b2326d9082

Buffered render hair drawing.

Currently all render hairs are drawn in the same place as the simulation
hair. OpenGL buffers are used for efficiency, which gives decent
performance even for many render hairs.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/intern/hair.c
M	source/blender/editors/space_view3d/drawhair.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesrna/intern/rna_hair.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f748057..35151be 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1263,6 +1263,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col.separator()
         
         col.label("Render:")
+        col2.prop(params, "render_hairs")
         col2.prop(params, "curl_smoothing")
         
         col.separator()
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index b07775a..f2126cd 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -52,6 +52,9 @@ HairSystem *BKE_hairsys_new(void)
 	hsys->params.bend_stiffness = 40.0f;
 	hsys->params.bend_damping = 10.0f;
 	
+	hsys->params.num_render_hairs = 100;
+	hsys->params.curl_smoothing = 1.0f;
+	
 	return hsys;
 }
 
@@ -63,6 +66,10 @@ void BKE_hairsys_free(HairSystem *hsys)
 			MEM_freeN(hsys->curves[i].points);
 		MEM_freeN(hsys->curves);
 	}
+	
+	if (hsys->display.drawdata)
+		MEM_freeN(hsys->display.drawdata);
+	
 	MEM_freeN(hsys);
 }
 
@@ -75,6 +82,8 @@ HairSystem *BKE_hairsys_copy(HairSystem *hsys)
 	for (i = 0; i < totcurves; ++i)
 		thsys->curves[i].points = MEM_dupallocN(hsys->curves[i].points);
 	
+	thsys->display.drawdata = NULL;
+	
 	return thsys;
 }
 
diff --git a/source/blender/editors/space_view3d/drawhair.c b/source/blender/editors/space_view3d/drawhair.c
index 5d3bfbe..06f7a38 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -29,6 +29,8 @@
  *  \ingroup spview3d
  */
 
+#include "MEM_guardedalloc.h"
+
 #include "DNA_hair_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -107,23 +109,84 @@ static void get_hair_root_frame(HairCurve *hair, float frame[3][3])
 	}
 }
 
+static int max_hair_points(HairSystem *hsys)
+{
+	HairCurve *hair;
+	int i;
+	
+	int max_points = 0;
+	for (i = 0, hair = hsys->curves; i < hsys->totcurves; ++i, ++hair) {
+		if (hair->totpoints > max_points)
+			max_points = hair->totpoints;
+	}
+	
+	return max_points;
+}
+
 static void draw_hair_render(HairSystem *hsys)
 {
 	const float scale = 0.2f;
+	int num_render_hairs = hsys->params.num_render_hairs;
+	
+	static unsigned int vertex_glbuf = 0;
+	static unsigned int elem_glbuf = 0;
+	
+	int maxpoints = max_hair_points(hsys);
+	int maxsteps = maxpoints; // TODO include interpolation
+	int maxverts = num_render_hairs * maxsteps;
+	int maxelems = num_render_hairs * 2 * (maxsteps-1);
+	
+	float (*vertex_data)[3];
+	unsigned int *elem_data;
 	
 	struct HAIR_FrameIterator *iter = HAIR_frame_iter_new();
 	int i;
 	
-	glBegin(GL_LINES);
+	if (maxelems < 1)
+		return;
+	
+#define USE_BUFFERS
+	
+#ifdef USE_BUFFERS
+	/* set up OpenGL buffers */
+	if (!vertex_glbuf) {
+		glGenBuffers(1, &vertex_glbuf);
+		glGenBuffers(1, &elem_glbuf);
+	}
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_glbuf);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elem_glbuf);
+	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * maxverts, NULL, GL_DYNAMIC_DRAW);
+	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * maxelems, NULL, GL_DYNAMIC_DRAW);
+	
+	glEnableClientState(GL_VERTEX_ARRAY);
+	
+	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), NULL);
+#else
+	vertex_data = MEM_mallocN(sizeof(float) * 3 * maxverts, "hair vertex data");
+	elem_data = MEM_mallocN(sizeof(unsigned int) * maxelems, "hair elem data");
+#endif
+	
+//	glEnable(GL_LIGHTING);
 	
 	for (i = 0; i < hsys->totcurves; ++i) {
 		HairCurve *hair = hsys->curves + i;
+		int totsteps = hair->totpoints; // TODO include interpolation
+		/*int totverts = num_render_hairs * totsteps;*/ /* unused */
+		int totelems = num_render_hairs * 2 * (totsteps-1);
+		unsigned int vertex_offset = 0;
+		unsigned int elem_offset = 0;
 		float initial_frame[3][3];
 		
 		get_hair_root_frame(hair, initial_frame);
 		
+#ifdef USE_BUFFERS
+		vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
+		elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
+#endif
+		
 		for (HAIR_frame_iter_init(iter, hair, hair->avg_rest_length, hsys->params.curl_smoothing, initial_frame); HAIR_frame_iter_valid(iter); HAIR_frame_iter_next(iter)) {
 			HairPoint *point = hair->points + HAIR_frame_iter_index(iter);
+			int a;
 			float co[3], nor[3], tan[3], cotan[3];
 			
 			copy_v3_v3(co, point->co);
@@ -135,21 +198,53 @@ static void draw_hair_render(HairSystem *hsys)
 			add_v3_v3(tan, co);
 			add_v3_v3(cotan, co);
 			
-			glColor3f(1.0f, 0.0f, 0.0f);
-			glVertex3fv(co);
-			glVertex3fv(nor);
-			glColor3f(0.0f, 1.0f, 0.0f);
-			glVertex3fv(co);
-			glVertex3fv(tan);
-			glColor3f(0.0f, 0.0f, 1.0f);
-			glVertex3fv(co);
-			glVertex3fv(cotan);
+			for (a = 0; a < num_render_hairs; ++a) {
+				copy_v3_v3(vertex_data[vertex_offset], co);
+				
+				if (HAIR_frame_iter_index(iter) < hair->totpoints - 1) {
+					elem_data[elem_offset] = vertex_offset;
+					elem_data[elem_offset + 1] = vertex_offset + 1;
+				}
+				
+				vertex_offset += 1;
+				elem_offset += 2;
+			}
+		}
+		
+#ifdef USE_BUFFERS
+		glUnmapBuffer(GL_ARRAY_BUFFER);
+		glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+		
+		/* draw */
+//		glShadeModel(GL_SMOOTH);
+		glDrawElements(GL_LINES, totelems, GL_UNSIGNED_INT, NULL);
+#else
+		{
+			int u;
+			glBegin(GL_LINES);
+			for (u = 0; u < totelems; ++u) {
+				glVertex3fv(vertex_data[elem_data[u]]);
+			}
+			glEnd();
 		}
+#endif
 	}
 	
-	glEnd();
+#ifdef USE_BUFFERS
+//	glDisable(GL_LIGHTING);
+	
+	glDisableClientState(GL_VERTEX_ARRAY);
+	
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+#else
+	MEM_freeN(vertex_data);
+	MEM_freeN(elem_data);
+#endif
 	
 	HAIR_frame_iter_free(iter);
+	
+#undef USE_BUFFERS
 }
 
 static void count_hairs(HairSystem *hsys, int *totpoints, int *validhairs)
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 1b1e5a6..169c3ee 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -72,12 +72,17 @@ typedef struct HairParams {
 	float margin;
 	
 	/* render settings */
+	int num_render_hairs;       /* render hairs per simulation hair */
+	
 	float curl_smoothing;
+	int pad;
 } HairParams;
 
 typedef struct HairDisplaySettings {
 	int mode;
 	int pad;
+	
+	struct HairDrawData *drawdata;  /* draw data cache */
 } HairDisplaySettings;
 
 typedef enum eHairDisplay_Mode {
diff --git a/source/blender/makesrna/intern/rna_hair.c b/source/blender/makesrna/intern/rna_hair.c
index 37551b6..bebbcb0 100644
--- a/source/blender/makesrna/intern/rna_hair.c
+++ b/source/blender/makesrna/intern/rna_hair.c
@@ -146,6 +146,13 @@ static void rna_def_hair_params(BlenderRNA *brna)
 
 	/* Render Settings */
 
+	prop = RNA_def_property(srna, "render_hairs", PROP_INT, PROP_UNSIGNED);
+	RNA_def_property_int_sdna(prop, NULL, "num_render_hairs");
+	RNA_def_property_range(prop, 1, 10000);
+	RNA_def_property_ui_range(prop, 1, 200, 1, 1);
+	RNA_def_property_int_default(prop, 100);
+	RNA_def_property_ui_text(prop, "Render Hairs", "Number of hairs rendered around each simulated hair");
+
 	prop = RNA_def_property(srna, "curl_smoothing", PROP_FLOAT, PROP_FACTOR);
 	RNA_def_property_float_sdna(prop, NULL, "curl_smoothing");
 	RNA_def_property_range(prop, 0.0f, 256.0f);




More information about the Bf-blender-cvs mailing list