diff options
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 126 |
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); |