Commit: c62468aabbdeae2c8e55ee5bfe86c73d98a123b2 Author: Antony Riakiotakis Date: Thu Oct 15 22:24:40 2015 +0300 Branches: master https://developer.blender.org/rBc62468aabbdeae2c8e55ee5bfe86c73d98a123b2
VBO implementation for GLSL subsurfed meshes (non-mapped case) As with cdderivedmesh, performance here is still CPU-limited if material needs tangents/UVs/vcolors. Draw calls have much less overhead though. Also, as with derivedmesh, kept an exception for old drawing for NVIDIA +OSX+VBO off or setDrawOptions callback not being NULL. setDrawOptions should be ommitable and fully VBOfialbe (?) in the future, usually those just check for hidden flag of poly or similar. =================================================================== M source/blender/blenkernel/intern/subsurf_ccg.c =================================================================== diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index f351ce0..a2c625a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -2705,6 +2705,13 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes) 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, @@ -2715,14 +2722,15 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, CCGSubSurf *ss = ccgdm->ss; CCGKey key; GPUVertexAttribs gattribs; - DMVertexAttribs attribs = {{{NULL}}}; - /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ + int a, b, do_draw, new_matnr; + 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); - DMFlagMat *faceFlags = ccgdm->faceFlags; - const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); - int a, i, do_draw, numVerts, matnr, new_matnr, totface; #ifdef WITH_OPENSUBDIV if (ccgdm->useGpuBackend) { @@ -2791,154 +2799,358 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, } #endif + glShadeModel(GL_SMOOTH); + CCG_key_top_level(&key, ss); ccgdm_pbvh_update(ccgdm); - do_draw = 0; - matnr = -1; + /* workaround for NVIDIA GPUs on Mac not supporting vertex arrays + interleaved formats, see T43342 */ + if ((GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY) && (U.gameflags & USER_DISABLE_VBO)) || + setDrawOptions != NULL) + { + const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); + DMVertexAttribs attribs = {{{NULL}}}; + int i; + int matnr = -1; + 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(&attribs, a, index, vert, ((a) * 4) + vert); \ } (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); - - numVerts = ccgSubSurf_getFaceNumVerts(f); - - 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; - } + 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); - if (new_matnr != matnr) { - do_draw = setMaterial(matnr = new_matnr, &gattribs); - if (do_draw) - DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); - } + int numVerts = ccgSubSurf_getFaceNumVerts(f); - if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && - (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP))) - { - a += gridFaces * gridFaces * numVerts; - continue; - } + if (faceFlags) { + drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH)); + new_matnr = faceFlags[index].mat_nr + 1; + } + else { + drawSmooth = 1; + new_matnr = 1; + } - glShadeModel(drawSmooth ? GL_SMOOTH : GL_FLAT); - for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - CCGElem *vda, *vdb; + if (lnors) { + ln = lnors; + lnors += (gridFaces * gridFaces * numVerts) * 4; + } - 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); + if (new_matnr != matnr) { + do_draw = setMaterial(matnr = new_matnr, &gattribs); + if (do_draw) + DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); + } - 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); + if (!do_draw || (setDrawOptions && (origIndex != ORIGINDEX_NONE) && + (setDrawOptions(userData, origIndex) == DM_DRAW_OPTION_SKIP))) + { + a += gridFaces * gridFaces * numVerts; + continue; + } - ln += 4; - a++; + 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(); } - glEnd(); - } - else if (drawSmooth) { - for (y = 0; y < gridFaces; y++) { - glBegin(GL_QUAD_STRIP); - for (x = 0; x < gridFaces; x++) { + 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, 0); + + PASSATTRIB(0, 0, 3); glNormal3fv(CCG_elem_no(&key, vda)); glVertex3fv(CCG_elem_co(&key, vda)); - PASSATTRIB(0, 1, 1); + PASSATTRIB(0, 1, 2); glNormal3fv(CCG_elem_no(&key, vdb)); glVertex3fv(CCG_elem_co(&key, vdb)); - if (x != gridFaces - 1) + 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(); + } + } + } - vda = CCG_grid_elem(&key, faceGridData, x, y + 0); - vdb = CCG_grid_elem(&key, faceGridData, x, y + 1); +#undef PASSATTRIB + } + else { + GPUMaterialConv *matconv; + size_t offset; + int *mat_orig_to_new; + int tot_active_mat; + GPUBuffer *buffer = NULL; - PASSATTRIB(0, 0, 3); - glNormal3fv(CCG_elem_no(&key, vda)); - glVertex3fv(CCG_elem_co(&key, vda)); + GPU_vertex_setup(dm); + GPU_normal_setup(dm); + GPU_triangle_setup(dm); - PASSATTRIB(0, 1, 2); - glNormal3fv(CCG_elem_no(&key, vdb)); - glVertex3fv(CCG_elem_co(&key, vdb)); + tot_active_mat = dm->drawObject->totmaterial; - glEnd(); + 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"); - a++; + /* part one, check what attributes are needed per material */ + for (a = 0; a < tot_active_mat; a++) { + 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].size = 3; + matconv[a]. @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs