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)) {

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to