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

Reply via email to