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:
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c126
1 files changed, 100 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index b0d19320230..04bcd366c3f 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -794,14 +794,20 @@ static void ss_sync_osd_from_derivedmesh(CCGSubSurf *ss,
static void ss_sync_from_derivedmesh(CCGSubSurf *ss,
DerivedMesh *dm,
float (*vertexCos)[3],
- int use_flat_subdiv)
+ int use_flat_subdiv,
+ bool use_subdiv_uvs)
{
+#ifndef WITH_OPENSUBDIV
+ UNUSED_VARS(use_subdiv_uvs);
+#endif
+
#ifdef WITH_OPENSUBDIV
/* Reset all related descriptors if actual mesh topology changed or if
* other evaluation-related settings changed.
*/
if (!ccgSubSurf_needGrids(ss)) {
/* TODO(sergey): Use vertex coordinates and flat subdiv flag. */
+ ccgSubSurf__sync_subdivUvs(ss, use_subdiv_uvs);
ccgSubSurf_checkTopologyChanged(ss, dm);
ss_sync_osd_from_derivedmesh(ss, dm);
}
@@ -1801,7 +1807,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEd
#ifdef WITH_OPENSUBDIV
if (ccgdm->useGpuBackend) {
/* TODO(sergey): We currently only support all edges drawing. */
- if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true)) {
+ if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) {
ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1);
}
return;
@@ -2638,7 +2644,7 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
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)) {
+ if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, setMaterial != NULL, -1) == false)) {
return;
}
if (setMaterial == NULL) {
@@ -2750,7 +2756,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
bool draw_smooth = false;
int start_draw_patch = -1, num_draw_patches = 0;
GPU_draw_update_fvar_offset(dm);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false) == false)) {
+ if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false, -1) == false)) {
return;
}
for (i = 0; i < num_base_faces; ++i) {
@@ -3193,7 +3199,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
int new_matnr;
bool draw_smooth;
GPU_draw_update_fvar_offset(dm);
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true) == false)) {
+ if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) {
return;
}
/* TODO(sergey): Single matierial currently. */
@@ -3386,19 +3392,6 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
int mat_index;
int tot_element, start_element, tot_drawn;
-#ifdef WITH_OPENSUBDIV
- if (ccgdm->useGpuBackend) {
- if (ccgSubSurf_prepareGLMesh(ss, true) == false) {
- return;
- }
- ccgSubSurf_drawGLMesh(ss, true, -1, -1);
- return;
- }
-#endif
-
- CCG_key_top_level(&key, ss);
- ccgdm_pbvh_update(ccgdm);
-
if (use_colors) {
colType = CD_TEXTURE_MLOOPCOL;
mloopcol = dm->getLoopDataArray(dm, colType);
@@ -3412,6 +3405,87 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
}
}
+#ifdef WITH_OPENSUBDIV
+ if (ccgdm->useGpuBackend) {
+ const int active_uv_layer = CustomData_get_active_layer_index(&dm->loopData, CD_MLOOPUV);
+ if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, active_uv_layer) == false)) {
+ return;
+ }
+ if (drawParams == NULL) {
+ ccgSubSurf_drawGLMesh(ss, true, -1, -1);
+ return;
+ }
+ 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 current_patch = 0;
+ int mat_nr = -1;
+ int start_draw_patch = 0, num_draw_patches = 0;
+ bool draw_smooth = false;
+ 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;
+ if (faceFlags) {
+ mat_nr = faceFlags[i].mat_nr;
+ draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
+ }
+ else {
+ mat_nr = 0;
+ draw_smooth = false;
+ }
+
+ if (drawParams != NULL) {
+ MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[i] : NULL;
+ draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
+ }
+ else {
+ draw_option = (drawParamsMapped)
+ ? drawParamsMapped(userData, i, mat_nr)
+ : DM_DRAW_OPTION_NORMAL;
+ }
+
+ flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1);
+
+ const int next_face = min_ii(i + 1, num_base_faces - 1);
+ if (!flush && compareDrawOptions) {
+ flush |= compareDrawOptions(userData, i, next_face) == 0;
+ }
+ if (!flush && faceFlags) {
+ bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH);
+ flush |= (new_draw_smooth != draw_smooth);
+ }
+
+ current_patch += num_patches;
+
+ if (flush) {
+ if (draw_option != DM_DRAW_OPTION_SKIP) {
+ num_draw_patches += num_patches;
+ }
+ if (num_draw_patches != 0) {
+ 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 = 0;
+ }
+ else {
+ num_draw_patches += num_patches;
+ }
+ }
+ return;
+ }
+#endif
+
+ CCG_key_top_level(&key, ss);
+ ccgdm_pbvh_update(ccgdm);
+
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
GPU_triangle_setup(dm);
@@ -3472,7 +3546,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
if (!flush && compareDrawOptions) {
/* also compare draw options and flush buffer if they're different
- * need for face selection highlight in edit mode */
+ * need for face selection highlight in edit mode */
flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
}
@@ -3581,7 +3655,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
*/
glColor3f(0.8f, 0.8f, 0.8f);
}
- if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true) == false)) {
+ if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) {
return;
}
if (faceFlags) {
@@ -3780,7 +3854,7 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm,
#ifdef WITH_OPENSUBDIV
if (ccgdm->useGpuBackend) {
/* TODO(sergey): Only draw edges from base mesh. */
- if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true)) {
+ if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) {
if (!setDrawOptions || (setDrawOptions(userData, 0) != DM_DRAW_OPTION_SKIP)) {
ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1);
}
@@ -4970,7 +5044,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
#ifdef WITH_OPENSUBDIV
ccgSubSurf_setSkipGrids(smd->emCache, use_gpu_backend);
#endif
- ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
+ ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv);
result = getCCGDerivedMesh(smd->emCache,
drawInteriorEdges,
useSubsurfUv, dm, use_gpu_backend);
@@ -4985,7 +5059,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS);
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
result = getCCGDerivedMesh(ss,
drawInteriorEdges, useSubsurfUv, dm, false);
@@ -5016,7 +5090,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) {
smd->mCache = ss = _getSubSurf(smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS);
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
result = getCCGDerivedMesh(smd->mCache,
drawInteriorEdges,
@@ -5056,7 +5130,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(
#ifdef WITH_OPENSUBDIV
ccgSubSurf_setSkipGrids(ss, use_gpu_backend);
#endif
- ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
+ ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv);
result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm, use_gpu_backend);
@@ -5085,7 +5159,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
CCGVertIterator vi;
DerivedMesh *dm = CDDM_from_mesh(me);
- ss_sync_from_derivedmesh(ss, dm, NULL, 0);
+ ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0);
for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) {
CCGVert *v = ccgVertIterator_getCurrent(&vi);