diff options
Diffstat (limited to 'source/blender/blenkernel/intern/subsurf_ccg.c')
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 2255 |
1 files changed, 10 insertions, 2245 deletions
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index e08560cccac..cead75ae659 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -69,6 +69,7 @@ #include "BKE_mesh_mapping.h" #include "BKE_modifier.h" #include "BKE_multires.h" +#include "BKE_object.h" #include "BKE_paint.h" #include "BKE_scene.h" #include "BKE_subsurf.h" @@ -77,12 +78,6 @@ # include "BLI_array.h" #endif -#include "GPU_draw.h" -#include "GPU_glew.h" -#include "GPU_buffers.h" -#include "GPU_shader.h" -#include "GPU_basic_shader.h" - #include "CCGSubSurf.h" #ifdef WITH_OPENSUBDIV @@ -1766,47 +1761,7 @@ static void ccgDM_foreachMappedLoop( } } -static void ccgDM_drawVerts(DerivedMesh *dm) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - CCGVertIterator vi; - CCGEdgeIterator ei; - CCGFaceIterator fi; - - glBegin(GL_POINTS); - for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { - CCGVert *v = ccgVertIterator_getCurrent(&vi); - glVertex3fv(ccgSubSurf_getVertData(ss, v)); - } - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - int x; - - for (x = 1; x < edgeSize - 1; x++) - glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); - } - - for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(&fi); - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - - glVertex3fv(ccgSubSurf_getFaceCenterData(f)); - for (S = 0; S < numVerts; S++) - for (x = 1; x < gridSize - 1; x++) - glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); - for (S = 0; S < numVerts; S++) - for (y = 1; y < gridSize - 1; y++) - for (x = 1; x < gridSize - 1; x++) - glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); - } - glEnd(); -} - -static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) +static void UNUSED_FUNCTION(ccgdm_pbvh_update)(CCGDerivedMesh *ccgdm) { if (ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) { CCGFace **faces; @@ -1821,2179 +1776,6 @@ static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) } } -static void ccgDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges) -{ - GPUDrawObject *gdo; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - /* TODO(sergey): We currently only support all edges drawing. */ - if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) { - ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1); - } - return; - } -#endif - - ccgdm_pbvh_update(ccgdm); - -/* old debug feature for edges, unsupported for now */ -#if 0 - int useAging = 0; - - if (!(G.f & G_BACKBUFSEL)) { - CCGSubSurf *ss = ccgdm->ss; - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - /* it needs some way to upload this to VBO now */ - if (useAging) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - } -#endif - - GPU_edge_setup(dm); - gdo = dm->drawObject; - if (gdo->edges && gdo->points) { - if (drawAllEdges && drawLooseEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, (gdo->totedge - gdo->totinterior) * 2); - } - else if (drawAllEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2); - } - else { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2); - GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, gdo->tot_loose_edge_drawn * 2); - } - } - - if (gdo->edges && ccgdm->drawInteriorEdges) { - GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->interior_offset * 2, gdo->totinterior * 2); - } - GPU_buffers_unbind(); -} - -static void ccgDM_drawLooseEdges(DerivedMesh *dm) -{ - int start; - int count; - -#ifdef WITH_OPENSUBDIV - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - if (ccgdm->useGpuBackend) { - /* TODO(sergey): Needs implementation. */ - return; - } -#endif - - GPU_edge_setup(dm); - - start = (dm->drawObject->loose_edge_offset * 2); - count = (dm->drawObject->interior_offset - dm->drawObject->loose_edge_offset) * 2; - - if (count) { - GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count); - } - - GPU_buffers_unbind(); -} - -static void ccgDM_NormalFast(float *a, float *b, float *c, float *d, float no[3]) -{ - float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; - float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; - - no[0] = b_dY * a_cZ - b_dZ * a_cY; - no[1] = b_dZ * a_cX - b_dX * a_cZ; - no[2] = b_dX * a_cY - b_dY * a_cX; - - normalize_v3(no); -} - - -static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) -{ - float a_cX = c[0] - a[0], a_cY = c[1] - a[1], a_cZ = c[2] - a[2]; - float b_dX = d[0] - b[0], b_dY = d[1] - b[1], b_dZ = d[2] - b[2]; - float no[3]; - - no[0] = b_dY * a_cZ - b_dZ * a_cY; - no[1] = b_dZ * a_cX - b_dX * a_cZ; - no[2] = b_dX * a_cY - b_dY * a_cX; - - /* don't normalize, GL_NORMALIZE is enabled */ - glNormal3fv(no); -} - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_normal( - DerivedMesh *dm, short *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int i, totface = ccgSubSurf_getNumFaces(ss); - int shademodel; - int start = 0; - - /* we are in sculpt mode, disable loop normals (since they won't get updated) */ - if (ccgdm->pbvh) - lnors = NULL; - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - const float (*ln)[3] = NULL; - - if (faceFlags) { - shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; - } - else { - shademodel = GL_SMOOTH; - } - - if (lnors) { - ln = lnors; - lnors += gridFaces * gridFaces * numVerts * 4; - } - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - - if (ln) { - /* Can't use quad strips here... */ - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - normal_float_to_short_v3(&varray[start + 0], ln[0]); - normal_float_to_short_v3(&varray[start + 4], ln[3]); - normal_float_to_short_v3(&varray[start + 8], ln[2]); - normal_float_to_short_v3(&varray[start + 12], ln[1]); - - start += 16; - ln += 4; - } - } - } - else if (shademodel == GL_SMOOTH) { - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - float *a = CCG_grid_elem_no(&key, faceGridData, x, y ); - float *b = CCG_grid_elem_no(&key, faceGridData, x + 1, y); - float *c = CCG_grid_elem_no(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_no(&key, faceGridData, x, y + 1); - - normal_float_to_short_v3(&varray[start], a); - normal_float_to_short_v3(&varray[start + 4], b); - normal_float_to_short_v3(&varray[start + 8], c); - normal_float_to_short_v3(&varray[start + 12], d); - - start += 16; - } - } - } - else { - for (y = 0; y < gridFaces; y ++) { - for (x = 0; x < gridFaces; x ++) { - float f_no[3]; - short f_no_s[3]; - - float *a = CCG_grid_elem_co(&key, faceGridData, x, y ); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y ); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_NormalFast(a, b, c, d, f_no); - normal_float_to_short_v3(f_no_s, f_no); - - copy_v3_v3_short(&varray[start], f_no_s); - copy_v3_v3_short(&varray[start + 4], f_no_s); - copy_v3_v3_short(&varray[start + 8], f_no_s); - copy_v3_v3_short(&varray[start + 12], f_no_s); - - start += 16; - } - } - } - } - } -} - -typedef struct FaceCount { - unsigned int i_visible; - unsigned int i_hidden; - unsigned int i_tri_visible; - unsigned int i_tri_hidden; -} FaceCount; - - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_triangles( - DerivedMesh *dm, unsigned int *varray, - const int *mat_orig_to_new) -{ - GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials; - const int gpu_totmat = dm->drawObject->totmaterial; - const short dm_totmat = dm->totmat; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int i, totface = ccgSubSurf_getNumFaces(ss); - short mat_nr = -1; - int start; - int totloops = 0; - FaceCount *fc = MEM_mallocN(sizeof(*fc) * gpu_totmat, "gpumaterial.facecount"); - - CCG_key_top_level(&key, ss); - - for (i = 0; i < gpu_totmat; i++) { - fc[i].i_visible = 0; - fc[i].i_tri_visible = 0; - fc[i].i_hidden = gpumaterials[i].totpolys - 1; - fc[i].i_tri_hidden = gpumaterials[i].totelements - 1; - } - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - bool is_hidden; - int mati; - - if (faceFlags) { - mat_nr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat); - is_hidden = (faceFlags[index].flag & ME_HIDE) != 0; - } - else { - mat_nr = 0; - is_hidden = false; - } - mati = mat_orig_to_new[mat_nr]; - gpumat = dm->drawObject->materials + mati; - - if (is_hidden) { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - start = gpumat->start + fc[mati].i_tri_hidden; - - varray[start--] = totloops; - varray[start--] = totloops + 2; - varray[start--] = totloops + 3; - - varray[start--] = totloops; - varray[start--] = totloops + 1; - varray[start--] = totloops + 2; - - fc[mati].i_tri_hidden -= 6; - - totloops += 4; - } - } - } - gpumat->polys[fc[mati].i_hidden--] = i; - } - else { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - start = gpumat->start + fc[mati].i_tri_visible; - - varray[start++] = totloops + 3; - varray[start++] = totloops + 2; - varray[start++] = totloops; - - varray[start++] = totloops + 2; - varray[start++] = totloops + 1; - varray[start++] = totloops; - - fc[mati].i_tri_visible += 6; - - totloops += 4; - } - } - } - gpumat->polys[fc[mati].i_visible++] = i; - } - } - - /* set the visible polygons */ - for (i = 0; i < gpu_totmat; i++) { - gpumaterials[i].totvisiblepolys = fc[i].i_visible; - } - - MEM_freeN(fc); -} - - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_vertex( - DerivedMesh *dm, void *varray_p) -{ - float *varray = varray_p; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int totedge = ccgSubSurf_getNumEdges(ss); - int start = 0; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - copy_v3_v3(&varray[start], a); - copy_v3_v3(&varray[start + 3], b); - copy_v3_v3(&varray[start + 6], c); - copy_v3_v3(&varray[start + 9], d); - - start += 12; - } - } - } - } - - /* upload loose points */ - for (i = 0; i < totedge; i++) { - CCGEdge *e = ccgdm->edgeMap[i].edge; - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - - if (!ccgSubSurf_getEdgeNumFaces(e)) { - int j = 0; - for (j = 0; j < edgeSize; j++) { - copy_v3_v3(&varray[start], CCG_elem_offset_co(&key, edgeData, j)); - start += 3; - } - } - } -} - -/* Only used by non-editmesh types */ -static void ccgDM_buffer_copy_color( - DerivedMesh *dm, unsigned char *varray, - const void *user_data) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - const unsigned char *mloopcol = user_data; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - int iface = 0; - - CCG_key_top_level(&key, ss); - - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - copy_v4_v4_uchar(&varray[start + 0], &mloopcol[iface * 16 + 0]); - copy_v4_v4_uchar(&varray[start + 4], &mloopcol[iface * 16 + 12]); - copy_v4_v4_uchar(&varray[start + 8], &mloopcol[iface * 16 + 8]); - copy_v4_v4_uchar(&varray[start + 12], &mloopcol[iface * 16 + 4]); - - start += 16; - iface++; - } - } - } - } -} - -static void ccgDM_buffer_copy_uv( - DerivedMesh *dm, void *varray_p) -{ - float *varray = varray_p; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - MLoopUV *mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - - CCG_key_top_level(&key, ss); - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - copy_v2_v2(&varray[start + 0], mloopuv[0].uv); - copy_v2_v2(&varray[start + 2], mloopuv[3].uv); - copy_v2_v2(&varray[start + 4], mloopuv[2].uv); - copy_v2_v2(&varray[start + 6], mloopuv[1].uv); - - mloopuv += 4; - start += 8; - } - } - } - } -} - -static void ccgDM_buffer_copy_uv_texpaint( - DerivedMesh *dm, float *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int i, totface = ccgSubSurf_getNumFaces(ss); - int start = 0; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int dm_totmat = dm->totmat; - MLoopUV **mloopuv_base; - MLoopUV *stencil_base; - int stencil; - - CCG_key_top_level(&key, ss); - - /* should have been checked for before, reassert */ - BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV)); - mloopuv_base = MEM_mallocN(dm_totmat * sizeof(*mloopuv_base), "texslots"); - - for (i = 0; i < dm_totmat; i++) { - mloopuv_base[i] = DM_paint_uvlayer_active_get(dm, i); - } - - stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV); - stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil); - - start = 0; - - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int matnr; - - if (faceFlags) { - matnr = faceFlags[index].mat_nr; - } - else { - matnr = 0; - } - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - /* divide by 4, gives us current loop-index */ - unsigned int i_ml = start / 4; - copy_v2_v2(&varray[start + 0], mloopuv_base[matnr][i_ml + 0].uv); - copy_v2_v2(&varray[start + 2], stencil_base[i_ml + 0].uv); - copy_v2_v2(&varray[start + 4], mloopuv_base[matnr][i_ml + 3].uv); - copy_v2_v2(&varray[start + 6], stencil_base[i_ml + 3].uv); - copy_v2_v2(&varray[start + 8], mloopuv_base[matnr][i_ml + 2].uv); - copy_v2_v2(&varray[start + 10], stencil_base[i_ml + 2].uv); - copy_v2_v2(&varray[start + 12], mloopuv_base[matnr][i_ml + 1].uv); - copy_v2_v2(&varray[start + 14], stencil_base[i_ml + 1].uv); - start += 16; - } - } - } - } - - MEM_freeN(mloopuv_base); -} - -static void ccgDM_buffer_copy_uvedge( - DerivedMesh *dm, float *varray) -{ - int i, totpoly; - int start; - const MLoopUV *mloopuv; -#ifndef USE_LOOP_LAYOUT_FAST - const MPoly *mpoly = dm->getPolyArray(dm); -#endif - - if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { - return; - } - - totpoly = dm->getNumPolys(dm); - start = 0; - -#ifndef USE_LOOP_LAYOUT_FAST - for (i = 0; i < totpoly; i++, mpoly++) { - for (j = 0; j < mpoly->totloop; j++) { - copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv); - copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv); - start += 4; - } - } -#else - for (i = 0; i < totpoly; i++) { - copy_v2_v2(&varray[start + 0], mloopuv[(i * 4) + 0].uv); - copy_v2_v2(&varray[start + 2], mloopuv[(i * 4) + 1].uv); - - copy_v2_v2(&varray[start + 4], mloopuv[(i * 4) + 1].uv); - copy_v2_v2(&varray[start + 6], mloopuv[(i * 4) + 2].uv); - - copy_v2_v2(&varray[start + 8], mloopuv[(i * 4) + 2].uv); - copy_v2_v2(&varray[start + 10], mloopuv[(i * 4) + 3].uv); - - copy_v2_v2(&varray[start + 12], mloopuv[(i * 4) + 3].uv); - copy_v2_v2(&varray[start + 14], mloopuv[(i * 4) + 0].uv); - - start += 16; - } -#endif -} - -static void ccgDM_buffer_copy_edge( - DerivedMesh *dm, unsigned int *varray) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - /* getEdgeSuze returns num of verts, edges is one less */ - int i, j, edgeSize = ccgSubSurf_getEdgeSize(ss) - 1; - int totedge = ccgSubSurf_getNumEdges(ss); - int grid_face_side = ccgSubSurf_getGridSize(ss) - 1; - int totface = ccgSubSurf_getNumFaces(ss); - unsigned int index_start; - unsigned int tot_interior = 0; - unsigned int grid_tot_face = grid_face_side * grid_face_side; - - unsigned int iloose, inorm, iloosehidden, inormhidden; - unsigned int tot_loose_hidden = 0, tot_loose = 0; - unsigned int tot_hidden = 0, tot = 0; - unsigned int iloosevert; - /* int tot_interior = 0; */ - - /* first, handle hidden/loose existing edges, then interior edges */ - for (j = 0; j < totedge; j++) { - CCGEdge *e = ccgdm->edgeMap[j].edge; - - if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) { - if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose_hidden++; - else tot_hidden++; - } - else { - if (!ccgSubSurf_getEdgeNumFaces(e)) tot_loose++; - else tot++; - } - } - - inorm = 0; - inormhidden = tot * edgeSize; - iloose = (tot + tot_hidden) * edgeSize; - iloosehidden = (tot + tot_hidden + tot_loose) * edgeSize; - iloosevert = dm->drawObject->tot_loop_verts; - - /* part one, handle all normal edges */ - for (j = 0; j < totedge; j++) { - CCGFace *f; - int fhandle = 0; - int totvert = 0; - unsigned int S = 0; - CCGEdge *e = ccgdm->edgeMap[j].edge; - bool isloose = !ccgSubSurf_getEdgeNumFaces(e); - - if (!isloose) { - CCGVert *v1, *v2; - CCGVert *ev1 = ccgSubSurf_getEdgeVert0(e); - CCGVert *ev2 = ccgSubSurf_getEdgeVert1(e); - - f = ccgSubSurf_getEdgeFace(e, 0); - fhandle = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - totvert = ccgSubSurf_getFaceNumVerts(f); - - /* find the index of vertices in the face */ - for (i = 0; i < totvert; i++) { - v1 = ccgSubSurf_getFaceVert(f, i); - v2 = ccgSubSurf_getFaceVert(f, (i + 1) % totvert); - - if ((ev1 == v1 && ev2 == v2) || (ev1 == v2 && ev2 == v1)) { - S = i; - break; - } - } - } - - if (ccgdm->edgeFlags && !(ccgdm->edgeFlags[j] & ME_EDGEDRAW)) { - if (isloose) { - for (i = 0; i < edgeSize; i++) { - varray[iloosehidden * 2] = iloosevert; - varray[iloosehidden * 2 + 1] = iloosevert + 1; - iloosehidden++; - iloosevert++; - } - /* we are through with this loose edge and moving to the next, so increase by one */ - iloosevert++; - } - else { - index_start = ccgdm->faceMap[fhandle].startFace; - - for (i = 0; i < grid_face_side; i++) { - varray[inormhidden * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1; - varray[inormhidden * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2; - varray[inormhidden * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2; - varray[inormhidden * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3; - inormhidden += 2; - } - } - } - else { - if (isloose) { - for (i = 0; i < edgeSize; i++) { - varray[iloose * 2] = iloosevert; - varray[iloose * 2 + 1] = iloosevert + 1; - iloose++; - iloosevert++; - } - /* we are through with this loose edge and moving to the next, so increase by one */ - iloosevert++; - } - else { - index_start = ccgdm->faceMap[fhandle].startFace; - - for (i = 0; i < grid_face_side; i++) { - varray[inorm * 2] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 1; - varray[inorm * 2 + 1] = (index_start + S * grid_tot_face + i * grid_face_side + grid_face_side - 1) * 4 + 2; - varray[inorm * 2 + 2] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 2; - varray[inorm * 2 + 3] = (index_start + ((S + 1) % totvert) * grid_tot_face + grid_face_side * (grid_face_side - 1) + i) * 4 + 3; - inorm += 2; - } - } - } - } - - /* part two, handle interior edges */ - inorm = totedge * grid_face_side * 2; - - index_start = 0; - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - unsigned int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - - for (S = 0; S < numVerts; S++) { - for (x = 1; x < grid_face_side; x++) { - for (y = 0; y < grid_face_side; y++) { - unsigned int tmp = (index_start + x * grid_face_side + y) * 4; - varray[inorm * 2] = tmp; - varray[inorm * 2 + 1] = tmp + 1; - inorm++; - } - } - for (x = 0; x < grid_face_side; x++) { - for (y = 0; y < grid_face_side; y++) { - unsigned int tmp = (index_start + x * grid_face_side + y) * 4; - varray[inorm * 2] = tmp + 3; - varray[inorm * 2 + 1] = tmp; - inorm++; - } - } - - tot_interior += grid_face_side * (2 * grid_face_side - 1); - index_start += grid_tot_face; - } - } - - dm->drawObject->tot_loose_edge_drawn = tot_loose * edgeSize; - dm->drawObject->loose_edge_offset = (tot + tot_hidden) * edgeSize; - dm->drawObject->tot_edge_drawn = tot * edgeSize; - - dm->drawObject->interior_offset = totedge * edgeSize; - dm->drawObject->totinterior = tot_interior; -} - -static void ccgDM_copy_gpu_data( - DerivedMesh *dm, int type, void *varray_p, - const int *mat_orig_to_new, const void *user_data) -{ - /* 'varray_p' cast is redundant but include for self-documentation */ - switch (type) { - case GPU_BUFFER_VERTEX: - ccgDM_buffer_copy_vertex(dm, (float *)varray_p); - break; - case GPU_BUFFER_NORMAL: - ccgDM_buffer_copy_normal(dm, (short *)varray_p); - break; - case GPU_BUFFER_UV: - ccgDM_buffer_copy_uv(dm, (float *)varray_p); - break; - case GPU_BUFFER_UV_TEXPAINT: - ccgDM_buffer_copy_uv_texpaint(dm, (float *)varray_p); - break; - case GPU_BUFFER_COLOR: - ccgDM_buffer_copy_color(dm, (unsigned char *)varray_p, user_data); - break; - case GPU_BUFFER_UVEDGE: - ccgDM_buffer_copy_uvedge(dm, (float *)varray_p); - break; - case GPU_BUFFER_EDGE: - ccgDM_buffer_copy_edge(dm, (unsigned int *)varray_p); - break; - case GPU_BUFFER_TRIANGLES: - ccgDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new); - break; - default: - break; - } -} - -static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - GPUDrawObject *gdo; - DMFlagMat *faceFlags = ccgdm->faceFlags; - int gridFaces = ccgSubSurf_getGridSize(ss) - 1; - const short dm_totmat = (faceFlags) ? dm->totmat : 1; - GPUBufferMaterial *matinfo; - int i; - unsigned int tot_internal_edges = 0; - int edgeVerts = ccgSubSurf_getEdgeSize(ss); - int edgeSize = edgeVerts - 1; - - int totedge = ccgSubSurf_getNumEdges(ss); - int totface = ccgSubSurf_getNumFaces(ss); - - /* object contains at least one material (default included) so zero means uninitialized dm */ - BLI_assert(dm_totmat != 0); - - matinfo = MEM_callocN(sizeof(*matinfo) * dm_totmat, "GPU_drawobject_new.mat_orig_to_new"); - - if (faceFlags) { - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - const short new_matnr = ME_MAT_NR_TEST(faceFlags[index].mat_nr, dm_totmat); - matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6; - matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4; - matinfo[new_matnr].totpolys++; - tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1); - } - } - else { - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - matinfo[0].totelements += numVerts * gridFaces * gridFaces * 6; - matinfo[0].totloops += numVerts * gridFaces * gridFaces * 4; - matinfo[0].totpolys++; - tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1); - } - } - - /* create the GPUDrawObject */ - gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); - gdo->totvert = 0; /* used to count indices, doesn't really matter for ccgsubsurf */ - gdo->totedge = (totedge * edgeSize + tot_internal_edges); - - GPU_buffer_material_finalize(gdo, matinfo, dm_totmat); - - /* store total number of points used for triangles */ - gdo->tot_triangle_point = ccgSubSurf_getNumFinalFaces(ss) * 6; - gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4; - - /* finally, count loose points */ - for (i = 0; i < totedge; i++) { - CCGEdge *e = ccgdm->edgeMap[i].edge; - - if (!ccgSubSurf_getEdgeNumFaces(e)) - gdo->tot_loose_point += edgeVerts; - } - - return gdo; -} - -/* Only used by non-editmesh types */ -static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], bool fast, DMSetMaterial setMaterial) -{ - int a; - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - - ccgdm_pbvh_update(ccgdm); - - if (ccgdm->pbvh && ccgdm->multires.mmd) { - if (BKE_pbvh_has_faces(ccgdm->pbvh)) { - BKE_pbvh_draw(ccgdm->pbvh, partial_redraw_planes, NULL, - setMaterial, false, fast); - } - - return; - } - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - CCGSubSurf *ss = ccgdm->ss; - 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, -1) == false)) { - return; - } - if (setMaterial == NULL) { - ccgSubSurf_drawGLMesh(ss, - true, - -1, - -1); - return; - } - 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(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); - } - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - for (a = 0; a < dm->drawObject->totmaterial; a++) { - if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) { - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, dm->drawObject->materials[a].start, - dm->drawObject->materials[a].totelements); - } - } - GPU_buffers_unbind(); -} - -typedef struct { - DMVertexAttribs attribs; - int numdata; - - GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ -} GPUMaterialConv; - -/* Only used by non-editmesh types */ -static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, - DMSetMaterial setMaterial, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - GPUVertexAttribs gattribs; - int a, b; - const DMFlagMat *faceFlags = ccgdm->faceFlags; - unsigned char *varray; - size_t max_element_size = 0; - int tot_loops = 0; - int totpoly = ccgSubSurf_getNumFaces(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - 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; - GPU_draw_update_fvar_offset(dm); - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, false, -1) == false)) { - return; - } - 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(mat_nr, &gattribs); - 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, &gattribs); - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - - if (setDrawOptions != NULL) { - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - DMVertexAttribs attribs = {{{NULL}}}; - int i; - int matnr = -1; - int do_draw = 0; - -#define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) \ - index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - else \ - index = 0; \ - DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \ - DM_draw_attrib_vertex_uniforms(&attribs); \ -} (void)0 - - totpoly = ccgSubSurf_getNumFaces(ss); - for (a = 0, i = 0; i < totpoly; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - const float (*ln)[3] = NULL; - int S, x, y, drawSmooth; - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int origIndex = ccgDM_getFaceMapIndex(ss, f); - - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int new_matnr; - - if (faceFlags) { - drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); - new_matnr = faceFlags[index].mat_nr + 1; - } - else { - drawSmooth = 1; - new_matnr = 1; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - if (new_matnr != matnr) { - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } - - if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && - (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP))) - { - a += gridFaces * gridFaces * numVerts; - continue; - } - - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - CCGElem *vda, *vdb; - - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 1, 1); - glNormal3fv(ln[1]); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glNormal3fv(ln[2]); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glNormal3fv(ln[3]); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glNormal3fv(ln[0]); - glVertex3fv(aco); - - ln += 4; - a++; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 0); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 1); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - if (x != gridFaces - 1) - a++; - } - - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 3); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 2); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - glEnd(); - - a++; - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(aco, bco, cco, dco); - - PASSATTRIB(0, 1, 1); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glVertex3fv(aco); - - a++; - } - } - glEnd(); - } - } - } - - glShadeModel(GL_SMOOTH); -#undef PASSATTRIB - } - else { - GPUMaterialConv *matconv; - size_t offset; - int *mat_orig_to_new; - int tot_active_mat; - GPUBuffer *buffer = NULL; - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - - tot_active_mat = dm->drawObject->totmaterial; - - matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat, - "cdDM_drawMappedFacesGLSL.matconv"); - mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat, - "cdDM_drawMappedFacesGLSL.mat_orig_to_new"); - - /* part one, check what attributes are needed per material */ - for (a = 0; a < tot_active_mat; a++) { - int new_matnr; - int do_draw; - - new_matnr = dm->drawObject->materials[a].mat_nr; - - /* map from original material index to new - * GPUBufferMaterial index */ - mat_orig_to_new[new_matnr] = a; - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - int numdata = 0; - DM_vertex_attributes_from_gpu(dm, &gattribs, &matconv[a].attribs); - - if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index; - matconv[a].datatypes[numdata].size = 3; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - for (b = 0; b < matconv[a].attribs.tottface; b++) { - if (matconv[a].attribs.tface[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index; - matconv[a].datatypes[numdata].size = 2; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.totmcol; b++) { - if (matconv[a].attribs.mcol[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE; - numdata++; - } - } - for (b = 0; b < matconv[a].attribs.tottang; b++) { - if (matconv[a].attribs.tottang && matconv[a].attribs.tang[b].array) { - matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index; - matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index; - matconv[a].datatypes[numdata].size = 4; - matconv[a].datatypes[numdata].type = GL_FLOAT; - numdata++; - } - } - if (numdata != 0) { - matconv[a].numdata = numdata; - max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size); - } - } - } - - /* part two, generate and fill the arrays with the data */ - if (max_element_size > 0) { - buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts); - - varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY); - if (varray == NULL) { - GPU_buffers_unbind(); - GPU_buffer_free(buffer); - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - fprintf(stderr, "Out of memory, can't draw object\n"); - return; - } - - for (a = 0; a < totpoly; a++) { - CCGFace *f = ccgdm->faceMap[a].face; - int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int i; - - if (faceFlags) { - i = mat_orig_to_new[faceFlags[orig_index].mat_nr]; - } - else { - i = mat_orig_to_new[0]; - } - - if (matconv[i].numdata != 0) { - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - - offset = tot_loops * max_element_size; - - if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) { - int index; - - index = getFaceIndex(ss, f, S, x, y, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x + 1, y, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + 2 * max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - index = getFaceIndex(ss, f, S, x, y + 1, edgeSize, gridSize); - copy_v3_v3((float *)&varray[offset + 3 * max_element_size], - (float *)matconv[i].attribs.orco.array[index]); - - offset += sizeof(float) * 3; - } - for (b = 0; b < matconv[i].attribs.tottface; b++) { - if (matconv[i].attribs.tface[b].array) { - const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array + tot_loops; - - copy_v2_v2((float *)&varray[offset], mloopuv[0].uv); - copy_v2_v2((float *)&varray[offset + max_element_size], mloopuv[3].uv); - copy_v2_v2((float *)&varray[offset + 2 * max_element_size], mloopuv[2].uv); - copy_v2_v2((float *)&varray[offset + 3 * max_element_size], mloopuv[1].uv); - - offset += sizeof(float) * 2; - } - } - for (b = 0; b < matconv[i].attribs.totmcol; b++) { - if (matconv[i].attribs.mcol[b].array) { - const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array + tot_loops; - - copy_v4_v4_uchar(&varray[offset], &mloopcol[0].r); - copy_v4_v4_uchar(&varray[offset + max_element_size], &mloopcol[3].r); - copy_v4_v4_uchar(&varray[offset + 2 * max_element_size], &mloopcol[2].r); - copy_v4_v4_uchar(&varray[offset + 3 * max_element_size], &mloopcol[1].r); - - offset += sizeof(unsigned char) * 4; - } - } - for (b = 0; b < matconv[i].attribs.tottang; b++) { - if (matconv[i].attribs.tottang && matconv[i].attribs.tang[b].array) { - const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang[b].array + tot_loops; - - copy_v4_v4((float *)&varray[offset], looptang[0]); - copy_v4_v4((float *)&varray[offset + max_element_size], looptang[3]); - copy_v4_v4((float *)&varray[offset + 2 * max_element_size], looptang[2]); - copy_v4_v4((float *)&varray[offset + 3 * max_element_size], looptang[1]); - - offset += sizeof(float) * 4; - } - } - - tot_loops += 4; - } - } - } - } - else { - tot_loops += 4 * numVerts * gridFaces * gridFaces; - } - } - GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY); - } - - for (a = 0; a < tot_active_mat; a++) { - int new_matnr; - int do_draw; - - new_matnr = dm->drawObject->materials[a].mat_nr; - - do_draw = setMaterial(new_matnr + 1, &gattribs); - - if (do_draw) { - if (matconv[a].numdata) { - GPU_interleaved_attrib_setup(buffer, matconv[a].datatypes, matconv[a].numdata, max_element_size); - } - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, - dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements); - if (matconv[a].numdata) { - GPU_interleaved_attrib_unbind(); - } - } - } - - GPU_buffers_unbind(); - if (buffer) - GPU_buffer_free(buffer); - - MEM_freeN(mat_orig_to_new); - MEM_freeN(matconv); - } -} - -static void ccgDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial) -{ - dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); -} - -/* Only used by non-editmesh types */ -static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, - void (*setMaterial)(void *userData, int matnr, void *attribs), - bool (*setFace)(void *userData, int index), void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - GPUVertexAttribs gattribs; - DMVertexAttribs attribs = {{{NULL}}}; - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - DMFlagMat *faceFlags = ccgdm->faceFlags; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int a, i, numVerts, matnr, totface; - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - 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; - bool draw_smooth = false; - int start_draw_patch = -1, num_draw_patches = 0; - GPU_draw_update_fvar_offset(dm); - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) { - return; - } - 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) { - setMaterial(userData, mat_nr, &gattribs); - 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) { - setMaterial(userData, mat_nr, &gattribs); - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, - true, - start_draw_patch, - num_draw_patches); - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - - matnr = -1; - -#define PASSATTRIB(dx, dy, vert) { \ - if (attribs.totorco) \ - index = getFaceIndex(ss, f, S, x + dx, y + dy, edgeSize, gridSize); \ - else \ - index = 0; \ - DM_draw_attrib_vertex(&attribs, a, index, vert, ((a) * 4) + vert); \ - DM_draw_attrib_vertex_uniforms(&attribs); \ -} (void)0 - - totface = ccgSubSurf_getNumFaces(ss); - for (a = 0, i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - const float (*ln)[3] = NULL; - int S, x, y, drawSmooth; - int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int origIndex = ccgDM_getFaceMapIndex(ss, f); - int new_matnr; - - numVerts = ccgSubSurf_getFaceNumVerts(f); - - /* get flags */ - if (faceFlags) { - drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); - new_matnr = faceFlags[index].mat_nr + 1; - } - else { - drawSmooth = 1; - new_matnr = 1; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - /* material */ - if (new_matnr != matnr) { - setMaterial(userData, matnr = new_matnr, &gattribs); - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } - - /* face hiding */ - if ((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) { - a += gridFaces * gridFaces * numVerts; - continue; - } - - /* draw face*/ - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - CCGElem *vda, *vdb; - - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 1, 1); - glNormal3fv(ln[1]); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glNormal3fv(ln[2]); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glNormal3fv(ln[3]); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glNormal3fv(ln[0]); - glVertex3fv(aco); - - ln += 4; - a++; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - vda = CCG_grid_elem(&key, faceGridData, x, y); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 0); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 1); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - if (x != gridFaces - 1) - a++; - } - - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); - - PASSATTRIB(0, 0, 3); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); - - PASSATTRIB(0, 1, 2); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); - - glEnd(); - - a++; - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(aco, bco, cco, dco); - - PASSATTRIB(0, 1, 1); - glVertex3fv(dco); - PASSATTRIB(1, 1, 2); - glVertex3fv(cco); - PASSATTRIB(1, 0, 3); - glVertex3fv(bco); - PASSATTRIB(0, 0, 0); - glVertex3fv(aco); - - a++; - } - } - glEnd(); - } - } - } - - glShadeModel(GL_SMOOTH); -#undef PASSATTRIB -} - -static void ccgDM_drawFacesTex_common(DerivedMesh *dm, - DMSetDrawOptionsTex drawParams, - DMSetDrawOptionsMappedTex drawParamsMapped, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - int colType; - const MLoopCol *mloopcol = NULL; - MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); - DMFlagMat *faceFlags = ccgdm->faceFlags; - DMDrawOption draw_option; - int i, totpoly; - bool flush; - const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0; - const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0; - unsigned int next_actualFace; - unsigned int gridFaces = ccgSubSurf_getGridSize(ss) - 1; - int mat_index; - int tot_element, start_element, tot_drawn; - - if (use_colors) { - colType = CD_TEXTURE_MLOOPCOL; - mloopcol = dm->getLoopDataArray(dm, colType); - if (!mloopcol) { - colType = CD_PREVIEW_MLOOPCOL; - mloopcol = dm->getLoopDataArray(dm, colType); - } - if (!mloopcol) { - colType = CD_MLOOPCOL; - mloopcol = dm->getLoopDataArray(dm, colType); - } - } - -#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; - } - } - glShadeModel(GL_SMOOTH); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgdm_pbvh_update(ccgdm); - - GPU_vertex_setup(dm); - GPU_normal_setup(dm); - GPU_triangle_setup(dm); - if (flag & DM_DRAW_USE_TEXPAINT_UV) - GPU_texpaint_uv_setup(dm); - else - GPU_uv_setup(dm); - if (mloopcol) { - GPU_color_setup(dm, colType); - } - - next_actualFace = 0; - - /* lastFlag = 0; */ /* UNUSED */ - for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { - GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; - next_actualFace = bufmat->polys[0]; - totpoly = bufmat->totpolys; - - tot_element = 0; - tot_drawn = 0; - start_element = 0; - - for (i = 0; i < totpoly; i++) { - int polyindex = bufmat->polys[i]; - CCGFace *f = ccgdm->faceMap[polyindex].face; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int index = ccgDM_getFaceMapIndex(ss, f); - int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - int mat_nr; - int facequads = numVerts * gridFaces * gridFaces; - int actualFace = ccgdm->faceMap[polyindex].startFace; - - if (i != totpoly - 1) { - polyindex = bufmat->polys[i + 1]; - next_actualFace = ccgdm->faceMap[polyindex].startFace; - } - - if (faceFlags) { - mat_nr = faceFlags[orig_index].mat_nr; - } - else { - mat_nr = 0; - } - - if (drawParams) { - MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[actualFace] : NULL; - draw_option = drawParams(tp, (mloopcol != NULL), mat_nr); - } - else if (index != ORIGINDEX_NONE) - draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL; - else - draw_option = DM_DRAW_OPTION_NORMAL; - - /* flush buffer if current triangle isn't drawable or it's last triangle */ - flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1); - - if (!flush && compareDrawOptions) { - /* also compare draw options and flush buffer if they're different - * need for face selection highlight in edit mode */ - flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; - } - - tot_element += facequads * 6; - - if (flush) { - if (draw_option != DM_DRAW_OPTION_SKIP) - tot_drawn += facequads * 6; - - if (tot_drawn) { - if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL) - GPU_color_switch(1); - else - GPU_color_switch(0); - - GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); - tot_drawn = 0; - } - - start_element = tot_element; - } - else { - tot_drawn += facequads * 6; - } - } - } - - - GPU_buffers_unbind(); -} - -static void ccgDM_drawFacesTex(DerivedMesh *dm, - DMSetDrawOptionsTex setDrawOptions, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag); -} - -static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, - DMSetDrawOptionsMappedTex setDrawOptions, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag); -} - -/* same as cdDM_drawUVEdges */ -static void ccgDM_drawUVEdges(DerivedMesh *dm) -{ - MPoly *mpoly = dm->getPolyArray(dm); - int totpoly = dm->getNumPolys(dm); - int prevstart = 0; - bool prevdraw = true; - int curpos = 0; - int i; - - GPU_uvedge_setup(dm); - for (i = 0; i < totpoly; i++, mpoly++) { - const bool draw = (mpoly->flag & ME_HIDE) == 0; - - if (prevdraw != draw) { - if (prevdraw && (curpos != prevstart)) { - glDrawArrays(GL_LINES, prevstart, curpos - prevstart); - } - prevstart = curpos; - } - - curpos += 2 * mpoly->totloop; - prevdraw = draw; - } - if (prevdraw && (curpos != prevstart)) { - glDrawArrays(GL_LINES, prevstart, curpos - prevstart); - } - GPU_buffers_unbind(); -} - -static void ccgDM_drawMappedFaces(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetMaterial setMaterial, - DMCompareDrawOptions compareDrawOptions, - void *userData, DMDrawFlag flag) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - MLoopCol *mloopcol = NULL; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int i, gridSize = ccgSubSurf_getGridSize(ss); - DMFlagMat *faceFlags = ccgdm->faceFlags; - int useColors = flag & DM_DRAW_USE_COLORS; - int gridFaces = gridSize - 1, totface; - int prev_mat_nr = -1; - - if (ccgdm->pbvh) { - if (G.debug_value == 14) - BKE_pbvh_draw_BB(ccgdm->pbvh); - } - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - int new_matnr; - bool draw_smooth, do_draw = true; - if (setDrawOptions == NULL) { - /* TODO(sergey): This is for cases when vertex colors or weights - * are visualising. Currently we don't have CD layers for this data - * and here we only make it so there's no garbage displayed. - * - * In the future we'll either need to have CD for this data or pass - * this data as face-varying or vertex-varying data in OSD mesh. - */ - glColor3f(0.8f, 0.8f, 0.8f); - } - if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, -1) == false)) { - return; - } - 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) { - setMaterial(new_matnr, NULL); - } - if (setDrawOptions) { - if (setDrawOptions(userData, 0) == DM_DRAW_OPTION_SKIP) { - do_draw = false; - } - } - if (do_draw) { - glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT); - ccgSubSurf_drawGLMesh(ss, true, -1, -1); - glShadeModel(GL_SMOOTH); - } - return; - } -#endif - - CCG_key_top_level(&key, ss); - - /* currently unused -- each original face is handled separately */ - (void)compareDrawOptions; - - if (useColors) { - mloopcol = dm->getLoopDataArray(dm, CD_PREVIEW_MLOOPCOL); - if (!mloopcol) - mloopcol = dm->getLoopDataArray(dm, CD_MLOOPCOL); - } - - totface = ccgSubSurf_getNumFaces(ss); - for (i = 0; i < totface; i++) { - CCGFace *f = ccgdm->faceMap[i].face; - int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); - int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); - int origIndex; - unsigned char *cp = NULL; - const float (*ln)[3] = NULL; - - origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - - if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1; - else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH)); - else drawSmooth = 1; - - if (mloopcol) { - cp = (unsigned char *)mloopcol; - mloopcol += gridFaces * gridFaces * numVerts * 4; - } - - if (lnors) { - ln = lnors; - lnors += (gridFaces * gridFaces * numVerts) * 4; - } - - { - DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - - if (setMaterial) { - int mat_nr = faceFlags ? faceFlags[origIndex].mat_nr + 1 : 1; - - if (mat_nr != prev_mat_nr) { - setMaterial(mat_nr, NULL); /* XXX, no faceFlags no material */ - prev_mat_nr = mat_nr; - } - } - - if (setDrawOptions && (index != ORIGINDEX_NONE)) - draw_option = setDrawOptions(userData, index); - - if (draw_option != DM_DRAW_OPTION_SKIP) { - if (draw_option == DM_DRAW_OPTION_STIPPLE) { - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - } - - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (ln) { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[4]); - glNormal3fv(ln[1]); - glVertex3fv(d); - if (cp) glColor4ubv(&cp[8]); - glNormal3fv(ln[2]); - glVertex3fv(c); - if (cp) glColor4ubv(&cp[12]); - glNormal3fv(ln[3]); - glVertex3fv(b); - if (cp) glColor4ubv(&cp[0]); - glNormal3fv(ln[0]); - glVertex3fv(a); - - if (cp) cp += 16; - ln += 4; - } - } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - CCGElem *a, *b; - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { - a = CCG_grid_elem(&key, faceGridData, x, y + 0); - b = CCG_grid_elem(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[0]); - glNormal3fv(CCG_elem_no(&key, a)); - glVertex3fv(CCG_elem_co(&key, a)); - if (cp) glColor4ubv(&cp[4]); - glNormal3fv(CCG_elem_no(&key, b)); - glVertex3fv(CCG_elem_co(&key, b)); - - if (x != gridFaces - 1) { - if (cp) cp += 16; - } - } - - a = CCG_grid_elem(&key, faceGridData, x, y + 0); - b = CCG_grid_elem(&key, faceGridData, x, y + 1); - - if (cp) glColor4ubv(&cp[12]); - glNormal3fv(CCG_elem_no(&key, a)); - glVertex3fv(CCG_elem_co(&key, a)); - if (cp) glColor4ubv(&cp[8]); - glNormal3fv(CCG_elem_no(&key, b)); - glVertex3fv(CCG_elem_co(&key, b)); - - if (cp) cp += 16; - - glEnd(); - } - } - else { - glBegin(GL_QUADS); - for (y = 0; y < gridFaces; y++) { - for (x = 0; x < gridFaces; x++) { - float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0); - float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0); - float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); - float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - - ccgDM_glNormalFast(a, b, c, d); - - if (cp) glColor4ubv(&cp[4]); - glVertex3fv(d); - if (cp) glColor4ubv(&cp[8]); - glVertex3fv(c); - if (cp) glColor4ubv(&cp[12]); - glVertex3fv(b); - if (cp) glColor4ubv(&cp[0]); - glVertex3fv(a); - - if (cp) cp += 16; - } - } - glEnd(); - } - } - if (draw_option == DM_DRAW_OPTION_STIPPLE) - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - } -} - -static void ccgDM_drawMappedEdges(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGEdgeIterator ei; - CCGKey key; - int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - /* TODO(sergey): Only draw edges from base mesh. */ - if (ccgSubSurf_prepareGLMesh(ccgdm->ss, true, -1)) { - if (!setDrawOptions || (setDrawOptions(userData, 0) != DM_DRAW_OPTION_SKIP)) { - ccgSubSurf_drawGLMesh(ccgdm->ss, false, -1, -1); - } - } - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int index = ccgDM_getEdgeMapIndex(ss, e); - - glBegin(GL_LINE_STRIP); - if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) { - if (useAging && !(G.f & G_BACKBUFSEL)) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - - for (i = 0; i < edgeSize - 1; i++) { - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i + 1)); - } - } - glEnd(); - } -} - -static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, - DMSetDrawOptions setDrawOptions, - DMSetDrawInterpOptions setDrawInterpOptions, - void *userData) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; - CCGSubSurf *ss = ccgdm->ss; - CCGKey key; - CCGEdgeIterator ei; - int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - -#ifdef WITH_OPENSUBDIV - if (ccgdm->useGpuBackend) { - BLI_assert(!"Not currently supported"); - return; - } -#endif - - CCG_key_top_level(&key, ss); - ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - - for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - int index = ccgDM_getEdgeMapIndex(ss, e); - - glBegin(GL_LINE_STRIP); - if (index != -1 && (!setDrawOptions || (setDrawOptions(userData, index) != DM_DRAW_OPTION_SKIP))) { - for (i = 0; i < edgeSize; i++) { - setDrawInterpOptions(userData, index, (float) i / (edgeSize - 1)); - - if (useAging && !(G.f & G_BACKBUFSEL)) { - int ageCol = 255 - ccgSubSurf_getEdgeAge(ss, e) * 4; - glColor3ub(0, ageCol > 0 ? ageCol : 0, 0); - } - - glVertex3fv(CCG_elem_offset_co(&key, edgeData, i)); - } - } - glEnd(); - } -} - static void ccgDM_foreachMappedFaceCenter( DerivedMesh *dm, void (*func)(void *userData, int index, const float co[3], const float no[3]), @@ -4036,7 +1818,7 @@ static void ccgDM_release(DerivedMesh *dm) if (ccgdm->multires.mmd) { if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) - multires_modifier_update_mdisps(dm); + multires_modifier_update_mdisps(dm, NULL); if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) multires_modifier_update_hidden(dm); } @@ -4537,7 +2319,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) numGrids, &key, (void **) ccgdm->gridFaces, ccgdm->gridFlagMats, ccgdm->gridHidden); } else if (ob->type == OB_MESH) { - Mesh *me = ob->data; + Mesh *me = BKE_object_get_original_mesh(ob); const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *looptri; @@ -4561,7 +2343,7 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) totvert = deformdm->getNumVerts(deformdm); vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos"); deformdm->getVertCos(deformdm, vertCos); - BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos); + BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos, totvert); MEM_freeN(vertCos); } } @@ -4678,23 +2460,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) ccgdm->dm.foreachMappedLoop = ccgDM_foreachMappedLoop; ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter; - ccgdm->dm.drawVerts = ccgDM_drawVerts; - ccgdm->dm.drawEdges = ccgDM_drawEdges; - ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges; - ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; - ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; - ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL; - ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; - ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex; - ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL; - ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat; - ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges; - - ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; - ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; - ccgdm->dm.gpuObjectNew = ccgDM_GPUObjectNew; - ccgdm->dm.copy_gpu_data = ccgDM_copy_gpu_data; - ccgdm->dm.release = ccgDM_release; } @@ -5146,8 +2911,7 @@ static bool subsurf_use_gpu_backend(SubsurfFlags flags) */ return (flags & SUBSURF_USE_GPU_BACKEND) != 0 && - (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE) && - (openSubdiv_supportGPUDisplay()); + (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE); #else (void)flags; return false; @@ -5157,6 +2921,7 @@ static bool subsurf_use_gpu_backend(SubsurfFlags flags) struct DerivedMesh *subsurf_make_derived_from_derived( struct DerivedMesh *dm, struct SubsurfModifierData *smd, + struct Scene *scene, float (*vertCos)[3], SubsurfFlags flags) { @@ -5170,7 +2935,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( /* note: editmode calculation can only run once per * modifier stack evaluation (uses freed cache) [#36299] */ if (flags & SUBSURF_FOR_EDIT_MODE) { - int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels, false) : smd->levels; + int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels; /* TODO(sergey): Same as emCache below. */ if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) { @@ -5191,7 +2956,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( else if (flags & SUBSURF_USE_RENDER_PARAMS) { /* Do not use cache in render mode. */ CCGSubSurf *ss; - int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->renderLevels, true) : smd->renderLevels; + int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->renderLevels, true) : smd->renderLevels; if (levels == 0) return dm; @@ -5207,7 +2972,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( } else { int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental); - int levels = (smd->modifier.scene) ? get_render_subsurf_level(&smd->modifier.scene->r, smd->levels, false) : smd->levels; + int levels = (scene != NULL) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels; CCGSubSurf *ss; /* It is quite possible there is a much better place to do this. It |