[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