[Bf-blender-cvs] [59efe23] strand_editmode: Primitive hair lighting in OpenGL solid shading, cleanup of strands drawing code for edit mode.

Lukas Tönne noreply at git.blender.org
Mon Apr 20 14:23:37 CEST 2015


Commit: 59efe23830dd84b1d56e83325eb9f25b7df0112b
Author: Lukas Tönne
Date:   Wed Dec 3 14:36:10 2014 +0100
Branches: strand_editmode
https://developer.blender.org/rB59efe23830dd84b1d56e83325eb9f25b7df0112b

Primitive hair lighting in OpenGL solid shading, cleanup of strands
drawing code for edit mode.

The lighting uses the same method as the particle hair, interpreting
strand direction as the normal. This is nowhere near realistic hair
shading, but doing this with line shading alone in the fixed-function
pipeline is probably not possible. A GLSL shader could be used instead
for a more realistic alternative as part of the viewport project. At
least this simple shading mode gives some orientation feedback while
editing hair.

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

M	source/blender/editors/space_view3d/drawstrands.c

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

diff --git a/source/blender/editors/space_view3d/drawstrands.c b/source/blender/editors/space_view3d/drawstrands.c
index 321b0a8..3aee274 100644
--- a/source/blender/editors/space_view3d/drawstrands.c
+++ b/source/blender/editors/space_view3d/drawstrands.c
@@ -51,8 +51,80 @@
 
 #include "view3d_intern.h"
 
-static void setup_gpu_buffers(BMEditStrands *edit)
+typedef enum StrandsShadeMode {
+	STRANDS_SHADE_FLAT,
+	STRANDS_SHADE_HAIR,
+} StrandsShadeMode;
+
+typedef struct StrandsDrawInfo {
+	bool has_zbuf;
+	bool use_zbuf_select;
+	
+	StrandsShadeMode shade_mode;
+	
+	float col_base[4];
+	float col_select[4];
+} StrandsDrawInfo;
+
+BLI_INLINE bool strands_use_normals(const StrandsDrawInfo *info)
+{
+	return ELEM(info->shade_mode, STRANDS_SHADE_HAIR);
+}
+
+static void init_draw_info(StrandsDrawInfo *info, View3D *v3d)
+{
+	info->has_zbuf = v3d->zbuf;
+	info->use_zbuf_select = (v3d->flag & V3D_ZBUF_SELECT);
+	
+	info->shade_mode = STRANDS_SHADE_HAIR;
+	
+	/* get selection theme colors */
+	UI_GetThemeColor4fv(TH_VERTEX, info->col_base);
+	UI_GetThemeColor4fv(TH_VERTEX_SELECT, info->col_select);
+}
+
+static void set_opengl_state(const StrandsDrawInfo *info)
+{
+	if (!info->use_zbuf_select)
+		glDisable(GL_DEPTH_TEST);
+	glEnable(GL_BLEND);
+	
+	if (ELEM(info->shade_mode, STRANDS_SHADE_HAIR)) {
+		glEnable(GL_LIGHTING);
+		glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+		glEnable(GL_COLOR_MATERIAL);
+		glShadeModel(GL_SMOOTH);
+	}
+	else {
+		glDisable(GL_LIGHTING);
+	}
+	
+	glEnableClientState(GL_VERTEX_ARRAY);
+	if (strands_use_normals(info))
+		glEnableClientState(GL_NORMAL_ARRAY);
+}
+
+static void restore_opengl_state(const StrandsDrawInfo *info)
+{
+	glDisableClientState(GL_NORMAL_ARRAY);
+	glDisableClientState(GL_VERTEX_ARRAY);
+	
+	glDisable(GL_BLEND);
+	glDisable(GL_LIGHTING);
+	glShadeModel(GL_FLAT);
+	if (info->has_zbuf)
+		glEnable(GL_DEPTH_TEST);
+	glLineWidth(1.0f);
+	glPointSize(1.0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void setup_gpu_buffers(BMEditStrands *edit, const StrandsDrawInfo *info)
 {
+	const size_t size_v3 = sizeof(float) * 3;
+	const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3);
+	
 //	int totstrands = BM_strands_count(edit->bm);
 	int totvert = edit->bm->totvert;
 	int totedge = edit->bm->totedge;
@@ -64,78 +136,90 @@ static void setup_gpu_buffers(BMEditStrands *edit)
 	
 	glBindBuffer(GL_ARRAY_BUFFER, edit->vertex_glbuf);
 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, edit->elem_glbuf);
-	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * totvert, NULL, GL_DYNAMIC_DRAW);
+	glBufferData(GL_ARRAY_BUFFER, size_vertex * totvert, NULL, GL_DYNAMIC_DRAW);
 	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * totedge * 2, NULL, GL_DYNAMIC_DRAW);
 	
-	glEnableClientState(GL_VERTEX_ARRAY);
-	
-	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), NULL);
+	glVertexPointer(3, GL_FLOAT, size_vertex, NULL);
+	if (strands_use_normals(info))
+		glNormalPointer(GL_FLOAT, size_vertex, (GLubyte *)NULL + size_v3);
 }
 
-static void release_gpu_buffers(void)
+static void unbind_gpu_buffers(void)
 {
-	glUnmapBuffer(GL_ARRAY_BUFFER);
-	glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+	glBindBuffer(GL_ARRAY_BUFFER, 0);
+	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 }
 
-void draw_strands_edit(Scene *UNUSED(scene), View3D *v3d, BMEditStrands *edit)
+static void write_gpu_buffers(BMEditStrands *edit, const StrandsDrawInfo *info)
 {
-	const bool zbuf_select = v3d->flag & V3D_ZBUF_SELECT;
-	float sel_col[3], nosel_col[3];
+	const size_t size_v3 = sizeof(float) * 3;
+	const size_t size_vertex = (strands_use_normals(info) ? 2*size_v3 : size_v3);
 	
-	float (*vertex_data)[3];
+	GLubyte *vertex_data;
 	unsigned int *elem_data;
-	BMVert *v;
-	BMEdge *e;
-	BMIter iter;
+	BMVert *root, *v, *vprev;
+	BMIter iter, iter_strand;
+	int index, indexprev, index_edge;
+	int k;
 	
-	/* get selection theme colors */
-	UI_GetThemeColor3fv(TH_VERTEX_SELECT, sel_col);
-	UI_GetThemeColor3fv(TH_VERTEX, nosel_col);
-	
-	/* opengl setup */
-	if (!zbuf_select)
-		glDisable(GL_DEPTH_TEST);
-	glEnable(GL_BLEND);
-	
-	//	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	//	glEnable(GL_COLOR_MATERIAL);
-	//	glShadeModel(GL_SMOOTH);
-		glDisable(GL_LIGHTING);
-	
-	setup_gpu_buffers(edit);
-	
-	/* initialize buffers */
 	vertex_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
 	elem_data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
 	
 	BM_mesh_elem_index_ensure(edit->bm, BM_VERT);
 	
-	BM_ITER_MESH(v, &iter, edit->bm, BM_VERTS_OF_MESH) {
-		int offset = BM_elem_index_get(v);
-		copy_v3_v3(vertex_data[offset], v->co);
+	index_edge = 0;
+	BM_ITER_STRANDS(root, &iter, edit->bm, BM_STRANDS_OF_MESH) {
+		BM_ITER_STRANDS_ELEM_INDEX(v, &iter_strand, root, BM_VERTS_OF_STRAND, k) {
+			size_t offset_co;
+			
+			index = BM_elem_index_get(v);
+			
+			offset_co = index * size_vertex;
+			copy_v3_v3((float *)(vertex_data + offset_co), v->co);
+			
+			if (k > 0) {
+				if (strands_use_normals(info)) {
+					size_t offset_nor = offset_co + size_v3;
+					float nor[3];
+					sub_v3_v3v3(nor, v->co, vprev->co);
+					normalize_v3(nor);
+					copy_v3_v3((float *)(vertex_data + offset_nor), nor);
+					
+					if (k == 1) {
+						/* define root normal: same as first segment */
+						size_t offset_root_nor = indexprev * size_vertex + size_v3;
+						copy_v3_v3((float *)(vertex_data + offset_root_nor), nor);
+					}
+				}
+				
+				{
+					elem_data[index_edge + 0] = indexprev;
+					elem_data[index_edge + 1] = index;
+					index_edge += 2;
+				}
+			}
+			
+			vprev = v;
+			indexprev = index;
+		}
 	}
 	
-	BM_ITER_MESH(e, &iter, edit->bm, BM_EDGES_OF_MESH) {
-		int offset = BM_elem_index_get(e) * 2;
-		elem_data[offset + 0] = BM_elem_index_get(e->v1);
-		elem_data[offset + 1] = BM_elem_index_get(e->v2);
-	}
+	glUnmapBuffer(GL_ARRAY_BUFFER);
+	glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
+}
+
+void draw_strands_edit(Scene *UNUSED(scene), View3D *v3d, BMEditStrands *edit)
+{
+	StrandsDrawInfo info;
 	
-	release_gpu_buffers();
+	init_draw_info(&info, v3d);
 	
-	glDrawElements(GL_LINES, edit->bm->totedge * 2, GL_UNSIGNED_INT, NULL);
+	set_opengl_state(&info);
 	
-	glDisableClientState(GL_NORMAL_ARRAY);
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glBindBuffer(GL_ARRAY_BUFFER, 0);
-	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+	setup_gpu_buffers(edit, &info);
+	write_gpu_buffers(edit, &info);
+	glDrawElements(GL_LINES, edit->bm->totedge * 2, GL_UNSIGNED_INT, NULL);
+	unbind_gpu_buffers();
 	
-	glDisable(GL_BLEND);
-	glDisable(GL_LIGHTING);
-	glShadeModel(GL_FLAT);
-	if (v3d->zbuf)
-		glEnable(GL_DEPTH_TEST);
-	glLineWidth(1.0f);
-	glPointSize(1.0);
+	restore_opengl_state(&info);
 }




More information about the Bf-blender-cvs mailing list