[Bf-blender-cvs] [c62468a] master: VBO implementation for GLSL subsurfed meshes (non-mapped case)
Antony Riakiotakis
noreply at git.blender.org
Thu Oct 15 22:21:52 CEST 2015
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. @@
More information about the Bf-blender-cvs
mailing list