[Bf-blender-cvs] [95963ce] opensubdiv-modifier: OpenSubdiv: Hook up UV attributes from OSD to GPU_material pipeline

Sergey Sharybin noreply at git.blender.org
Fri Jul 25 13:02:06 CEST 2014


Commit: 95963cefa36dc88063e07e2716f5e77d46836147
Author: Sergey Sharybin
Date:   Fri Jul 25 16:36:46 2014 +0600
Branches: opensubdiv-modifier
https://developer.blender.org/rB95963cefa36dc88063e07e2716f5e77d46836147

OpenSubdiv: Hook up UV attributes from OSD to GPU_material pipeline

For now active UV map is used for all the attributes, but that's
rather simple to fix now.

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

M	intern/opensubdiv/opensubdiv_capi.cc
M	intern/opensubdiv/opensubdiv_capi.h
M	source/blender/blenkernel/intern/CCGSubSurf.c
M	source/blender/blenkernel/intern/CCGSubSurf.h
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/gpu/intern/gpu_codegen.c
M	source/blender/gpu/intern/gpu_codegen.h
M	source/blender/gpu/shaders/gpu_shader_geometry.glsl

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

diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index e4400be..9b4c0aa 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -319,7 +319,8 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
     OpenSubdiv_EvaluatorDescr *evaluator_descr,
     int controller_type,
     int level,
-    int scheme)
+    int scheme,
+    int subdivide_uvs)
 {
 	OpenSubdiv_ComputeController *controller =
 		openSubdiv_getController(controller_type);
@@ -345,7 +346,9 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
 	get_partition_per_face(*hmesh, &idsOnPtexFaces);
 
 	hmesh->SetFVarInterpolateBoundaryMethod(
-	        OsdHbrMesh::k_InterpolateBoundaryNone);
+	        subdivide_uvs
+	            ? OsdHbrMesh::k_InterpolateBoundaryEdgeAndCorner
+	            : OsdHbrMesh::k_InterpolateBoundaryNone);
 	hmesh->SetFVarPropagateCorners(false);
 
 	OsdMeshBitset bits;
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index 0e18080..b20e95a 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -67,7 +67,8 @@ OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
     OpenSubdiv_EvaluatorDescr *evaluator_descr,
     int controller_type,
     int level,
-    int scheme);
+    int scheme,
+    int subdivide_uvs);
 
 void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh);
 unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer(
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index cfc17c8..a8858cf 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -473,6 +473,7 @@ struct CCGSubSurf {
 
 	bool osd_uvs_invalid;
 	int osd_uv_index;
+	bool osd_subsurf_uv;
 #endif
 };
 
@@ -939,6 +940,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *a
 		ss->osd_compute = 0;
 		ss->osd_uvs_invalid = false;
 		ss->osd_uv_index = -1;
+		ss->osd_subsurf_uv = 0;
 #endif
 
 		return ss;
@@ -2367,7 +2369,8 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl)
 			ss->osd_evaluator,
 			compute_type,
 			ss->subdivLevels,
-			scheme);
+			scheme,
+			ss->osd_subsurf_uv);
 
 		if (UNLIKELY(ss->osd_mesh == NULL)) {
 			/* Most likely compute device is not available. */
@@ -2543,7 +2546,9 @@ static bool opensubdiv_initEvaluator(CCGSubSurf *ss)
 	                                       scheme) != 0;
 }
 
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, DerivedMesh *dm)
+void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
+                                  DerivedMesh *dm,
+                                  bool subdivide_uvs)
 {
 	/* TODO(sergey): Do we have shorter way to do this? */
 	int active = CustomData_get_active_layer(&dm->loopData,
@@ -2559,12 +2564,17 @@ void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, DerivedMesh *dm)
 		ss->osd_uvs_invalid = true;
 	}
 
+	if (subdivide_uvs != ss->osd_subsurf_uv) {
+		ss->osd_uvs_invalid = true;
+	}
+
 	if (mloopuv == NULL || !ss->osd_uvs_invalid) {
 		return;
 	}
 
 	ss->osd_uvs_invalid = false;
 	ss->osd_uv_index = active;
+	ss->osd_subsurf_uv = subdivide_uvs;
 	if (ss->osd_mesh) {
 		ss->osd_mesh_invalid = true;
 	}
@@ -3097,6 +3107,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
 
 	ss->osd_coords_invalid = true;
 
+
 	/* Make sure OSD evaluator is up-to-date. */
 	if (opensubdiv_ensureEvaluator(ss)) {
 		if (ss->skip_grids == false) {
@@ -3107,6 +3118,7 @@ static void ccgSubSurf__sync(CCGSubSurf *ss)
 			opensubdiv_evaluateGrids(ss);
 		}
 		else {
+			BLI_assert(ss->meshIFC.numLayers == 3);
 			opensubdiv_updateCoarseNormals(ss);
 		}
 	}
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index db74a59..9e40835 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -196,7 +196,9 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
 void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids);
 
 struct DerivedMesh;
-void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss, struct DerivedMesh *dm);
+void ccgSubSurf_setUVCoordsFromDM(CCGSubSurf *ss,
+                                  struct DerivedMesh *dm,
+                                  bool subdivide_uvs);
 #endif
 
 #endif  /* __CCGSUBSURF_H__ */
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index e191d95..ea00bd5 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -4288,7 +4288,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
 				ccgSubSurf_setNumLayers(ss, 4);
 
 #ifdef WITH_OPENSUBDIV
-			ccgSubSurf_setUVCoordsFromDM(ss, dm);
+			ccgSubSurf_setUVCoordsFromDM(ss, dm, useSubsurfUv);
 #endif
 		}
 	}
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index b29ed64..93a2cef 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -641,10 +641,48 @@ static char *code_generate_fragment(ListBase *nodes, GPUOutput *output, const ch
 	return code;
 }
 
-static char *code_generate_geometry(bool use_opensubdiv)
+static char *code_generate_geometry(ListBase *nodes, bool use_opensubdiv)
 {
 	if (use_opensubdiv) {
-		return datatoc_gpu_shader_geometry_glsl;
+		DynStr *ds = BLI_dynstr_new();
+		GPUNode *node;
+		GPUInput *input;
+		char *code;
+
+		/* Generate varying declarations. */
+		for (node = nodes->first; node; node = node->next) {
+			for (input = node->inputs.first; input; input = input->next) {
+				if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+					if (input->attribtype == CD_MTFACE) {
+						BLI_dynstr_appendf(ds, "varying %s var%d;\n",
+						                   GPU_DATATYPE_STR[input->type],
+						                   input->attribid);
+					}
+				}
+			}
+		}
+
+		BLI_dynstr_append(ds, datatoc_gpu_shader_geometry_glsl);
+
+		/* Generate varying assignments. */
+		for (node = nodes->first; node; node = node->next) {
+			for (input = node->inputs.first; input; input = input->next) {
+				if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+					if (input->attribtype == CD_MTFACE) {
+						BLI_dynstr_appendf(ds, "\tvar%d  = outpt.v.uv;\n",
+						                   input->attribid);
+					}
+				}
+			}
+		}
+
+		BLI_dynstr_append(ds, "}\n\n");
+		code = BLI_dynstr_get_cstring(ds);
+		BLI_dynstr_free(ds);
+
+		//if (G.debug & G_DEBUG) printf("%s\n", code);
+
+		return code;
 	}
 	return NULL;
 }
@@ -659,10 +697,17 @@ static char *code_generate_vertex(ListBase *nodes)
 	for (node=nodes->first; node; node=node->next) {
 		for (input=node->inputs.first; input; input=input->next) {
 			if (input->source == GPU_SOURCE_ATTRIB && input->attribfirst) {
+				bool is_mtface = input->attribtype == CD_MTFACE;
+				if (is_mtface) {
+					BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+				}
 				BLI_dynstr_appendf(ds, "attribute %s att%d;\n",
 					GPU_DATATYPE_STR[input->type], input->attribid);
 				BLI_dynstr_appendf(ds, "varying %s var%d;\n",
 					GPU_DATATYPE_STR[input->type], input->attribid);
+				if (is_mtface) {
+					BLI_dynstr_appendf(ds, "#endif\n");
+				}
 			}
 		}
 	}
@@ -677,8 +722,16 @@ static char *code_generate_vertex(ListBase *nodes)
 					BLI_dynstr_appendf(ds, "\tvar%d.xyz = normalize((gl_ModelViewMatrix * vec4(att%d.xyz, 0)).xyz);\n", input->attribid, input->attribid);
 					BLI_dynstr_appendf(ds, "\tvar%d.w = att%d.w;\n", input->attribid, input->attribid);
 				}
-				else
+				else {
+					bool is_mtface = input->attribtype == CD_MTFACE;
+					if (is_mtface) {
+						BLI_dynstr_appendf(ds, "#ifndef USE_OPENSUBDIV\n");
+					}
 					BLI_dynstr_appendf(ds, "\tvar%d = att%d;\n", input->attribid, input->attribid);
+					if (is_mtface) {
+						BLI_dynstr_appendf(ds, "#endif\n");
+					}
+				}
 			}
 			/* unfortunately special handling is needed here because we abuse gl_Color/gl_SecondaryColor flat shading */
 			else if (input->source == GPU_SOURCE_OPENGL_BUILTIN) {
@@ -1415,7 +1468,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
 
 	/* generate code and compile with opengl */
 	fragmentcode = code_generate_fragment(nodes, outlink->output, name);
-	geometrycode = code_generate_geometry(use_opensubdiv);
+	geometrycode = code_generate_geometry(nodes, use_opensubdiv);
 	vertexcode = code_generate_vertex(nodes);
 	shader = GPU_shader_create(vertexcode, geometrycode, fragmentcode, glsl_material_library, NULL);
 
@@ -1433,6 +1486,7 @@ GPUPass *GPU_generate_pass(ListBase *nodes, GPUNodeLink *outlink, GPUVertexAttri
 	pass->output = outlink->output;
 	pass->shader = shader;
 	pass->fragmentcode = fragmentcode;
+	pass->geometrycode = geometrycode;
 	pass->vertexcode = vertexcode;
 	pass->libcode = glsl_material_library;
 
@@ -1449,6 +1503,8 @@ void GPU_pass_free(GPUPass *pass)
 	GPU_inputs_free(&pass->inputs);
 	if (pass->fragmentcode)
 		MEM_freeN(pass->fragmentcode);
+	if (pass->geometrycode)
+		MEM_freeN(pass->geometrycode);
 	if (pass->vertexcode)
 		MEM_freeN(pass->vertexcode);
 	MEM_freeN(pass);
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index dde8daf..656c49f 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -167,6 +167,7 @@ struct GPUPass {
 	struct GPUOutput *output;
 	struct GPUShader *shader;
 	char *fragmentcode;
+	char *geometrycode;
 	char *vertexcode;
 	const char *libcode;
 };
diff --git a/source/blender/gpu/shaders/gpu_shader_geometry.glsl b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
index 544eca9..4069d9e 100644
--- a/source/blender/gpu/shaders/gpu_shader_geometry.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_geometry.glsl
@@ -29,6 +29,8 @@ out block {
 	VertexData v;
 } outpt;
 
+void set_mtface_vertex_attrs();
+
 void emit_flat(int index, vec3 normal)
 {
 	outpt.v.position = inpt[index].v.position;
@@ -44,6 +46,8 @@ void emit_flat(int index, vec3 normal)
 
 	INTERP_FACE_VARYING_2(o

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list