Revision: 39777
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39777
Author:   nazgul
Date:     2011-08-29 16:07:44 +0000 (Mon, 29 Aug 2011)
Log Message:
-----------
Fix #28347: VBO's highlights wrong faces when Mirror modifier is in use

Added callback to drawMappedFaces which checks if two faces have got equal draw 
options.

After discussion with Brecht we found it's nicest solution for now:
- Disabling VBOs in edit mode for this case wouldn't be nicer for this case -
  some additional flag stored in DM should be added in this case.
- Adding new callback in DM isn't nicer that this solution.
- Handling face selection in drawobject would lead to duplicated code
  which is also not nice.

Hopefully, this callback could handle all cases in the future.

Also, Brecht mentioned current VBO implementation isn't perfect, so maybe
when we'll redesign this area dealing with edit mode wouldn't be so tricky.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
    trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
    trunk/blender/source/blender/editors/space_view3d/drawmesh.c
    trunk/blender/source/blender/editors/space_view3d/drawobject.c

Modified: trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h   2011-08-29 
15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/BKE_DerivedMesh.h   2011-08-29 
16:07:44 UTC (rev 39777)
@@ -283,7 +283,8 @@
                                                        int 
(*setDrawOptions)(void *userData, int index,
                                                                                
                  int *drawSmooth_r),
                                                        void *userData, int 
useColors,
-                                                       int (*setMaterial)(int, 
void *attribs));
+                                                       int (*setMaterial)(int, 
void *attribs),
+                                                       int 
(*compareDrawOptions)(void *userData, int cur_index, int next_index));
 
        /* Draw mapped faces using MTFace 
         *  o Drawing options too complicated to enumerate, look at code.

Modified: trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c        
2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/DerivedMesh.c        
2011-08-29 16:07:44 UTC (rev 39777)
@@ -637,7 +637,8 @@
 }
 
 /* note, material function is ignored for now. */
-static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int 
UNUSED(useColors), int (*setMaterial)(int, void *attribs))
+static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int 
UNUSED(useColors), int (*setMaterial)(int, void *attribs),
+                       int (*compareDrawOptions)(void *userData, int 
cur_index, int next_index))
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditFace *efa;
@@ -645,6 +646,9 @@
        
        (void)setMaterial; /* unused */
 
+       /* currently unused -- each original face is handled separately */
+       (void)compareDrawOptions;
+
        if (emdm->vertexCos) {
                EditVert *eve;
 

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c      
2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c      
2011-08-29 16:07:44 UTC (rev 39777)
@@ -843,7 +843,8 @@
        cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
 }
 
-static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int useColors, int 
(*setMaterial)(int, void *attribs))
+static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int useColors, int 
(*setMaterial)(int, void *attribs),
+                       int (*compareDrawOptions)(void *userData, int 
cur_index, int next_index))
 {
        CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
        MVert *mv = cddm->mvert;
@@ -958,6 +959,7 @@
                                        MFace *mface= mf + actualFace;
                                        int drawSmooth= (mface->flag & 
ME_SMOOTH);
                                        int draw = 1;
+                                       int flush = 0;
 
                                        if(i != tottri-1)
                                                next_actualFace= 
dm->drawObject->triangle_to_mface[i+1];
@@ -972,11 +974,28 @@
                                        /* Goal is to draw as long of a 
contiguous triangle
                                           array as possible, so draw when we 
hit either an
                                           invisible triangle or at the end of 
the array */
-                                       if(!draw || i == tottri - 1 || 
mf[actualFace].mat_nr != mf[next_actualFace].mat_nr) {
-                                               if(prevstart != i)
-                                                       /* Add one to the 
length (via `draw')
-                                                          if we're drawing at 
the end of the array */
-                                                       
glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3);
+
+                                       /* flush buffer if current triangle 
isn't drawable or it's last triangle... */
+                                       flush= !draw || i == tottri - 1;
+
+                                       /* ... or when material setting is 
dissferent  */
+                                       flush|= mf[actualFace].mat_nr != 
mf[next_actualFace].mat_nr;
+
+                                       if(!flush && compareDrawOptions) {
+                                               int next_orig= (index==NULL) ? 
next_actualFace : index[next_actualFace];
+
+                                               /* also compare draw options 
and flush buffer if they're different
+                                                  need for face selection 
highlight in edit mode */
+                                               flush|= 
compareDrawOptions(userData, orig, next_orig) == 0;
+                                       }
+
+                                       if(flush) {
+                                               int first= prevstart*3;
+                                               int count= (i-prevstart+(draw ? 
1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
+
+                                               if(count)
+                                                       
glDrawArrays(GL_TRIANGLES, first, count);
+
                                                prevstart = i + 1;
                                        }
                                }

Modified: trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c        
2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c        
2011-08-29 16:07:44 UTC (rev 39777)
@@ -1779,7 +1779,8 @@
        }
 }
 
-static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int useColors, int 
(*setMaterial)(int, void *attribs)) {
+static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void 
*userData, int index, int *drawSmooth_r), void *userData, int useColors, int 
(*setMaterial)(int, void *attribs),
+                       int (*compareDrawOptions)(void *userData, int 
cur_index, int next_index)) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
        MCol *mcol= NULL;
@@ -1787,6 +1788,9 @@
        char *faceFlags = ccgdm->faceFlags;
        int gridFaces = gridSize - 1, totface;
 
+       /* currently unused -- each original face is handled separately */
+       (void)compareDrawOptions;
+
        if(useColors) {
                mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
                if(!mcol)

Modified: trunk/blender/source/blender/editors/space_view3d/drawmesh.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawmesh.c        
2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/editors/space_view3d/drawmesh.c        
2011-08-29 16:07:44 UTC (rev 39777)
@@ -607,7 +607,7 @@
        }
        else if(faceselect) {
                if(ob->mode & OB_MODE_WEIGHT_PAINT)
-                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, 
me, 1, GPU_enable_material);
+                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, 
me, 1, GPU_enable_material, NULL);
                else
                        dm->drawMappedFacesTex(dm, me->mface ? 
draw_tface_mapped__set_draw : NULL, me);
        }

Modified: trunk/blender/source/blender/editors/space_view3d/drawobject.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/drawobject.c      
2011-08-29 15:01:55 UTC (rev 39776)
+++ trunk/blender/source/blender/editors/space_view3d/drawobject.c      
2011-08-29 16:07:44 UTC (rev 39777)
@@ -2030,6 +2030,28 @@
        return 0;
 }
 
+static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, 
int next_index)
+{
+       struct { unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+       EditFace *efa = EM_get_face_for_index(index);
+       EditFace *next_efa = EM_get_face_for_index(next_index);
+       unsigned char *col, *next_col;
+
+       if(efa == next_efa)
+               return 1;
+
+       if(efa == data->efa_act || next_efa == data->efa_act)
+               return 0;
+
+       col = data->cols[(efa->f&SELECT)?1:0];
+       next_col = data->cols[(next_efa->f&SELECT)?1:0];
+
+       if(col[3]==0 || next_col[3]==0)
+               return 0;
+
+       return col == next_col;
+}
+
 /* also draws the active face */
 static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, 
unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 {
@@ -2039,7 +2061,7 @@
        data.cols[2] = actCol;
        data.efa_act = efa_act;
 
-       dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, 
GPU_enable_material);
+       dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0, 
GPU_enable_material, draw_dm_faces_sel__compareDrawOptions);
 }
 
 static int draw_dm_creases__setDrawOptions(void *UNUSED(userData), int index)
@@ -2449,7 +2471,7 @@
                        glEnable(GL_LIGHTING);
                        glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
-                       finalDM->drawMappedFaces(finalDM, 
draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material);
+                       finalDM->drawMappedFaces(finalDM, 
draw_em_fancy__setFaceOpts, NULL, 0, GPU_enable_material, NULL);
 
                        glFrontFace(GL_CCW);
                        glDisable(GL_LIGHTING);
@@ -2678,7 +2700,7 @@
                        /* weight paint in solid mode, special case. focus on 
making the weights clear
                         * rather than the shading, this is also forced in wire 
view */
                        GPU_enable_material(0, NULL);
-                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, 
me->mface, 1, GPU_enable_material);
+                       dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, 
me->mface, 1, GPU_enable_material, NULL);
                
                        bglPolygonOffset(rv3d->dist, 1.0);
                        glDepthMask(0); // disable write in zbuffer, selected 
edge wires show better
@@ -2758,7 +2780,7 @@
                                glEnable(GL_LIGHTING);
                                glEnable(GL_COLOR_MATERIAL);
 
-                               dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material);
+                               dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, me->mface, 1, GPU_enable_material, NULL);
                                glDisable(GL_COLOR_MATERIAL);
                                glDisable(GL_LIGHTING);
 
@@ -2766,10 +2788,10 @@
                        }
                        else if(ob->mode & 
(OB_MODE_VERTEX_PAINT|OB_MODE_TEXTURE_PAINT)) {
                                if(me->mcol)
-                                       dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material);
+                                       dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, NULL, 1, GPU_enable_material, NULL);
                                else {
                                        glColor3f(1.0f, 1.0f, 1.0f);
-                                       dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material);
+                                       dm->drawMappedFaces(dm, 
wpaint__setSolidDrawOptions, NULL, 0, GPU_enable_material, NULL);
                                }
                        }
                }
@@ -6459,7 +6481,7 @@
        cpack(0);
 
        if (facecol) {
-               dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, 
(void*)(intptr_t) 1, 0, GPU_enable_material);
+               dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, 
(void*)(intptr_t) 1, 0, GPU_enable_material, NULL);
 
                if(check_ob_drawface_dot(scene, v3d, ob->dt)) {
                        glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE));
@@ -6470,7 +6492,7 @@
                }
 
        } else {
-               dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, 
(void*) 0, 0, GPU_enable_material);
+               dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, 
(void*) 0, 0, GPU_enable_material, NULL);
        }
 }
 
@@ -6499,8 +6521,8 @@
        
        glColor3ub(0, 0, 0);
                

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to