Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-08-25 16:05:28 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-08-25 16:11:56 +0300
commitf1e68474e051667b85ac804bded8fa2c8e0ff374 (patch)
tree9e3470179f56bff64807d944ad8af32141fcbc45 /source/blender/blenkernel
parent50917edad54d2be0f5e3a6630382e28ab1fd32e0 (diff)
OpenSubdiv: Support for multiple materials in solid shading mode
Implementation is less optimal compared to non-opensubdiv drawing but it is now as good as we can do it without affecting on how patches are being created by OpenSubdiv.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h6
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c25
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c79
3 files changed, 94 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h
index e9ad4c52531..a825cffe7a0 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.h
+++ b/source/blender/blenkernel/intern/CCGSubSurf.h
@@ -215,6 +215,12 @@ bool ccgSubSurf_prepareGLMesh(CCGSubSurf *ss, bool use_osd_glsl);
void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
int start_partition, int num_partitions);
+/* Get number of base faces in a particular GL mesh. */
+int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss);
+
+/* Get number of vertices in base faces in a particular GL mesh. */
+int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face);
+
/* Controls whether CCG are needed (Cmeaning CPU evaluation) or fully GPU compute
* and draw is allowed.
*/
diff --git a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
index eb7c3bf6ffd..fcc46308efa 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf_opensubdiv.c
@@ -308,6 +308,31 @@ void ccgSubSurf_drawGLMesh(CCGSubSurf *ss, bool fill_quads,
}
}
+int ccgSubSurf_getNumGLMeshBaseFaces(CCGSubSurf *ss)
+{
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
+ if (ss->osd_topology_refiner != NULL) {
+ topology_refiner = ss->osd_topology_refiner;
+ }
+ else {
+ topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
+ }
+ return openSubdiv_topologyRefinerGetNumFaces(topology_refiner);
+}
+
+/* Get number of vertices in base faces in a particular GL mesh. */
+int ccgSubSurf_getNumGLMeshBaseFaceVerts(CCGSubSurf *ss, int face)
+{
+ const OpenSubdiv_TopologyRefinerDescr *topology_refiner;
+ if (ss->osd_topology_refiner != NULL) {
+ topology_refiner = ss->osd_topology_refiner;
+ }
+ else {
+ topology_refiner = openSubdiv_getGLMeshTopologyRefiner(ss->osd_mesh);
+ }
+ return openSubdiv_topologyRefinerGetNumFaceVerts(topology_refiner, face);
+}
+
void ccgSubSurf_setSkipGrids(CCGSubSurf *ss, bool skip_grids)
{
ss->skip_grids = skip_grids;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index e38d62cd9bc..867065b060d 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -2622,24 +2622,72 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
#ifdef WITH_OPENSUBDIV
if (ccgdm->useGpuBackend) {
CCGSubSurf *ss = ccgdm->ss;
- DMFlagMat *faceFlags = ccgdm->faceFlags;
- int new_matnr;
- bool draw_smooth;
+ const DMFlagMat *faceFlags = ccgdm->faceFlags;
+ const int level = ccgSubSurf_getSubdivisionLevels(ss);
+ const int face_side = 1 << level;
+ const int grid_side = 1 << (level - 1);
+ const int face_patches = face_side * face_side;
+ const int grid_patches = grid_side * grid_side;
+ const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
+ int i, current_patch = 0;
+ int mat_nr = -1;
+ bool draw_smooth = false;
+ int start_draw_patch = -1, num_draw_patches = 0;
if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, setMaterial != NULL) == false)) {
return;
}
- /* TODO(sergey): Single matierial currently. */
- if (faceFlags) {
- draw_smooth = (faceFlags[0].flag & ME_SMOOTH);
- new_matnr = (faceFlags[0].mat_nr + 1);
- }
- else {
- draw_smooth = true;
- new_matnr = 1;
+ if (setMaterial == NULL) {
+ ccgSubSurf_drawGLMesh(ss,
+ true,
+ -1,
+ -1);
+ return;
}
- if (setMaterial && setMaterial(new_matnr, NULL)) {
- glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
- ccgSubSurf_drawGLMesh(ss, true, -1, -1);
+ for (i = 0; i < num_base_faces; ++i) {
+ const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
+ const int num_patches = (num_face_verts == 4) ? face_patches
+ : num_face_verts * grid_patches;
+ int new_matnr;
+ bool new_draw_smooth;
+ if (faceFlags) {
+ new_draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
+ new_matnr = (faceFlags[i].mat_nr + 1);
+ }
+ else {
+ new_draw_smooth = true;
+ new_matnr = 1;
+ }
+ if (new_draw_smooth != draw_smooth || new_matnr != mat_nr) {
+ if (num_draw_patches != 0) {
+ bool do_draw = setMaterial == NULL ||
+ setMaterial(mat_nr, NULL);
+ if (do_draw) {
+ glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
+ ccgSubSurf_drawGLMesh(ss,
+ true,
+ start_draw_patch,
+ num_draw_patches);
+ }
+ }
+ start_draw_patch = current_patch;
+ num_draw_patches = num_patches;
+ mat_nr = new_matnr;
+ draw_smooth = new_draw_smooth;
+ }
+ else {
+ num_draw_patches += num_patches;
+ }
+ current_patch += num_patches;
+ }
+ if (num_draw_patches != 0) {
+ bool do_draw = setMaterial(mat_nr, NULL);
+ if (do_draw) {
+ glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
+ ccgSubSurf_drawGLMesh(ss,
+ true,
+ start_draw_patch,
+ num_draw_patches);
+ }
}
return;
}
@@ -4528,8 +4576,7 @@ static void set_ccgdm_gpu_geometry(CCGDerivedMesh *ccgdm, DerivedMesh *dm)
for (index = 0; index < totface; index++) {
faceFlags->flag = mpoly ? mpoly[index].flag : 0;
- /* faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0; */
- faceFlags->mat_nr = 0;
+ faceFlags->mat_nr = mpoly ? mpoly[index].mat_nr : 0;
faceFlags++;
}