[Bf-blender-cvs] [29960e0] opensubdiv-modifier: OpenSubdiv; Simple subdivisions now uses bilinear subdivisions from OSD

Sergey Sharybin noreply at git.blender.org
Fri Jul 4 16:50:15 CEST 2014


Commit: 29960e08a3b599421abc06c3a57d37aa5aa93d03
Author: Sergey Sharybin
Date:   Fri Jul 4 20:45:34 2014 +0600
https://developer.blender.org/rB29960e08a3b599421abc06c3a57d37aa5aa93d03

OpenSubdiv; Simple subdivisions now uses bilinear subdivisions from OSD

This replaces fallback mode to a legacy implementation and uses new API
from OpenSubdiv to create mesh with bilinear subdivisions.

This requires latest OSD library from our cuda-dynload branch and blender
now can't be compiled with the precompiled library on Windows.

This also brings a bit of a regression for CPU-side simple subdivisions
calculation because there's some bug in OSD which leads to some curvature
when using adaptive subdivisions/

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

M	intern/opensubdiv/gpu_shader_opensubd_display.glsl
M	intern/opensubdiv/opensubdiv_capi.cc
M	intern/opensubdiv/opensubdiv_capi.h
M	intern/opensubdiv/opensubdiv_gpu_capi.cc
M	source/blender/blenkernel/intern/CCGSubSurf.c
M	source/blender/blenkernel/intern/subsurf_ccg.c

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

diff --git a/intern/opensubdiv/gpu_shader_opensubd_display.glsl b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
index b7daa45..cc5fb03 100644
--- a/intern/opensubdiv/gpu_shader_opensubd_display.glsl
+++ b/intern/opensubdiv/gpu_shader_opensubd_display.glsl
@@ -50,6 +50,10 @@ void main()
 	 */
 	gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
 #endif
+
+#ifdef WIREFRAME
+	gl_FrontColor = gl_Color;
+#endif
 }
 
 #endif  /* VERTEX_SHADER */
@@ -64,8 +68,16 @@ in vec3 varying_position;
 
 void main()
 {
+#ifdef WIREFRAME
+	gl_FragColor = gl_Color;
+#else
 	/* Compute normal. */
+#ifdef SMOOTH_SHADING
 	vec3 N = varying_normal;
+#else
+	vec3 N = normalize(cross(dFdx(varying_position),
+	                         dFdy(varying_position)));
+#endif
 
 	if (!gl_FrontFacing)
 		N = -N;
@@ -103,6 +115,7 @@ void main()
 
 	/* Write out fragment color. */
 	gl_FragColor = vec4(L, alpha);
+#endif
 }
 
 #endif  // FRAGMENT_SHADER
diff --git a/intern/opensubdiv/opensubdiv_capi.cc b/intern/opensubdiv/opensubdiv_capi.cc
index c80df7f..72267ba 100644
--- a/intern/opensubdiv/opensubdiv_capi.cc
+++ b/intern/opensubdiv/opensubdiv_capi.cc
@@ -246,10 +246,25 @@ static OpenSubdiv_ComputeController *openSubdiv_getController(
 	return NULL;
 }
 
+static OpenSubdiv::OsdUtilMesh<OsdVertex>::Scheme get_osd_scheme(int scheme)
+{
+	switch (scheme) {
+		case OPENSUBDIV_SCHEME_CATMARK:
+			return OpenSubdiv::OsdUtilMesh<OsdVertex>::SCHEME_CATMARK;
+		case OPENSUBDIV_SCHEME_BILINEAR:
+			return OpenSubdiv::OsdUtilMesh<OsdVertex>::SCHEME_BILINEAR;
+		case OPENSUBDIV_SCHEME_LOOP:
+			return OpenSubdiv::OsdUtilMesh<OsdVertex>::SCHEME_LOOP;
+		default:
+			assert(!"Wrong subdivision scheme");
+	}
+}
+
 struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
     OpenSubdiv_EvaluatorDescr *evaluator_descr,
     int controller_type,
-    int level)
+    int level,
+    int scheme)
 {
 	OpenSubdiv_ComputeController *controller =
 		openSubdiv_getController(controller_type);
@@ -263,7 +278,9 @@ struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
 	topology = (OsdUtilSubdivTopology *)openSubdiv_getEvaluatorTopologyDescr(
 		evaluator_descr);
 
-	if (util_mesh.Initialize(*topology) == false) {
+	if (util_mesh.Initialize(*topology,
+	                         NULL,
+	                         get_osd_scheme(scheme)) == false) {
 		return NULL;
 	}
 
diff --git a/intern/opensubdiv/opensubdiv_capi.h b/intern/opensubdiv/opensubdiv_capi.h
index ccf88be..5b61328 100644
--- a/intern/opensubdiv/opensubdiv_capi.h
+++ b/intern/opensubdiv/opensubdiv_capi.h
@@ -56,10 +56,17 @@ enum {
 	OPENSUBDIV_CONTROLLER_GLSL_COMPUTE             = (1 << 5),
 };
 
+enum {
+	OPENSUBDIV_SCHEME_CATMARK,
+	OPENSUBDIV_SCHEME_BILINEAR,
+	OPENSUBDIV_SCHEME_LOOP,
+};
+
 struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromEvaluator(
     struct OpenSubdiv_EvaluatorDescr *evaluator_descr,
     int controller_type,
-    int level);
+    int level,
+    int scheme);
 
 void openSubdiv_deleteOsdGLMesh(struct OpenSubdiv_GLMesh *gl_mesh);
 unsigned int openSubdiv_getOsdGLMeshPatchIndexBuffer(struct OpenSubdiv_GLMesh *gl_mesh);
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 33a678e..99cc664 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -45,7 +45,6 @@
 
 using OpenSubdiv::OsdGLMeshInterface;
 
-#ifndef OPENSUBDIV_LEGACY_DRAW
 extern "C" char datatoc_gpu_shader_opensubd_display_glsl[];
 
 static GLuint compileShader(GLenum shaderType,
@@ -109,33 +108,50 @@ static GLuint linkProgram(const char *define)
 
 	return program;
 }
-#endif  /* OPENSUBDIV_LEGACY_DRAW */
 
 void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, int fill_quads)
 {
+	static GLuint flat_fill_program;
 #ifndef OPENSUBDIV_LEGACY_DRAW
-	static GLuint quad_fill_program = 0;
+	static GLuint smooth_fill_program;
+	static GLuint wireframe_program;
+#endif
 	static bool need_init = true;
 
 	if (need_init) {
-		quad_fill_program = linkProgram("");
+		flat_fill_program = linkProgram("#define FLAT_SHADING\n");
+#ifndef OPENSUBDIV_LEGACY_DRAW
+		smooth_fill_program = linkProgram("#define SMOOTH_SHADING\n");
+		wireframe_program = linkProgram("#define WIREFRAME\n");
+#endif
 		need_init = false;
 	}
-#endif
 
 	OsdGLMeshInterface *mesh = (OsdGLMeshInterface *) gl_mesh->descriptor;
 
 	using OpenSubdiv::OsdDrawContext;
 	using OpenSubdiv::FarPatchTables;
 
-	const OsdDrawContext::PatchArrayVector &patches = mesh->GetDrawContext()->patchArrays;
-
-#ifndef OPENSUBDIV_LEGACY_DRAW
-	glUseProgram(quad_fill_program);
-#endif
+	const OsdDrawContext::PatchArrayVector &patches =
+		mesh->GetDrawContext()->patchArrays;
 
 	if (!fill_quads) {
 		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+#ifndef OPENSUBDIV_LEGACY_DRAW
+		glUseProgram(wireframe_program);
+#endif
+	}
+	else {
+		int model;
+		glGetIntegerv(GL_SHADE_MODEL, &model);
+		if (model == GL_FLAT) {
+			glUseProgram(flat_fill_program);
+		}
+#ifndef OPENSUBDIV_LEGACY_DRAW
+		else {
+			glUseProgram(smooth_fill_program);
+		}
+#endif
 	}
 
 	for (int i = 0; i < (int)patches.size(); ++i) {
@@ -156,8 +172,6 @@ void openSubdiv_osdGLMeshDisplay(OpenSubdiv_GLMesh *gl_mesh, int fill_quads)
 		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 	}
 	glBindVertexArray(0);
-#ifndef OPENSUBDIV_LEGACY_DRAW
 	/* TODO(sergey): Store previously used program and roll back to it? */
 	glUseProgram(0);
-#endif
 }
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index e282ada..a99cf13 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -671,6 +671,7 @@ static int _edge_isBoundary(const CCGEdge *e)
 	return e->numFaces < 2;
 }
 
+#ifndef WITH_OPENSUBDIV
 static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ)
 {
 	if (vQ == e->v0) {
@@ -680,6 +681,7 @@ static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ)
 		return e->v0;
 	}
 }
+#endif
 
 static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize)
 {
@@ -2341,10 +2343,15 @@ void ccgSubSurf_prepareGLMesh(CCGSubSurf *ss)
 	}
 
 	if (ss->osd_mesh == NULL) {
+		int scheme = ss->meshIFC.simpleSubdiv
+		             ? OPENSUBDIV_SCHEME_BILINEAR
+		             : OPENSUBDIV_SCHEME_CATMARK;
+
 		ss->osd_mesh = openSubdiv_createOsdGLMeshFromEvaluator(
 			ss->osd_evaluator,
 			compute_type,
-			ss->subdivLevels);
+			ss->subdivLevels,
+			scheme);
 
 		if (UNLIKELY(ss->osd_mesh == NULL)) {
 			/* Most likely compute device is not available. */
@@ -2962,7 +2969,7 @@ static void opensubdiv_evaluateGrids(CCGSubSurf *ss)
 	}
 }
 
-static void ccgSubSurf__syncOpenSubdiv(CCGSubSurf *ss)
+static void ccgSubSurf__sync(CCGSubSurf *ss)
 {
 	BLI_assert(ss->meshIFC.numLayers == 2 || ss->meshIFC.numLayers == 3);
 
@@ -2987,12 +2994,15 @@ static void ccgSubSurf__syncOpenSubdiv(CCGSubSurf *ss)
 	else {
 		BLI_assert(!"OpenSubdiv initializetion failed, should not happen.");
 	}
+
+#ifdef DUMP_RESULT_GRIDS
+	ccgSubSurf__dumpCoords(ss);
+#endif
 }
 
 #  undef OSD_LOG
-#endif  /* WITH_OPENSUBDIV */
-
-static void ccgSubSurf__syncLegacy(CCGSubSurf *ss)
+#else  /* WITH_OPENSUBDIV */
+static void ccgSubSurf__sync(CCGSubSurf *ss)
 {
 	CCGVert **effectedV;
 	CCGEdge **effectedE;
@@ -3271,26 +3281,12 @@ static void ccgSubSurf__syncLegacy(CCGSubSurf *ss)
 	MEM_freeN(effectedF);
 	MEM_freeN(effectedE);
 	MEM_freeN(effectedV);
-}
-
-static void ccgSubSurf__sync(CCGSubSurf *ss)
-{
-#ifdef WITH_OPENSUBDIV
-	if (ss->meshIFC.simpleSubdiv) {
-		/* Somple subdivisions we currently fallback to legacy code. */
-		ccgSubSurf__syncLegacy(ss);
-	}
-	else {
-		ccgSubSurf__syncOpenSubdiv(ss);
-	}
-#else
-	ccgSubSurf__syncLegacy(ss);
-#endif
 
 #ifdef DUMP_RESULT_GRIDS
-		ccgSubSurf__dumpCoords(ss);
+	ccgSubSurf__dumpCoords(ss);
 #endif
 }
+#endif  /* WITH_OPENSUBDIV */
 
 static void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces)
 {
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index fb49569..77099aa 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1661,7 +1661,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEd
 	int useAging;
 
 #ifdef WITH_OPENSUBDIV
-	if (!ccgSubSurf_getSimpleSubdiv(ss)) {
+	{
 		/* TODO(sergey): We currently only support all edges drawing. */
 		ccgSubSurf_prepareGLMesh(ss);
 		ccgSubSurf_drawGLMesh(ss, false);
@@ -1786,7 +1786,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
 	int drawcurrent = 0, matnr = -1, shademodel = -1;
 
 #ifdef WITH_OPENSUBDIV
-	if (!ccgSubSurf_getSimpleSubdiv(ss)) {
+	{
 		int matnr, shademodel;
 
 		/* TODO(sergey): This is just for the purposes of tests. */
@@ -3980,9 +3980,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
 			bool use_gpu_backend = false;
 
 #ifdef WITH_OPENSUBDIV
-			if (!useSimple) {
-				use_gpu_backend = (flags & SUBSURF_USE_GPU_BACKEND) != 0;
-			}
+			use_gpu_backend = (flags & SUBSURF_USE_GPU_BACKEND) != 0;
 #endif
 
 			if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) {




More information about the Bf-blender-cvs mailing list