Fix drawing of armature bone axes, these were not showing labels.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 19 Sep 2009 18:45:31 +0000 (18:45 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 19 Sep 2009 18:45:31 +0000 (18:45 +0000)
Also unified drawing code for object & particle text, was almost
the same function duplicated, and now also used for bones.

source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_intern.h

index 497091f2660aee42d2b17b5425a1460c1c2214ab..028d666dc71955901452fe02249979affb52485d 100644 (file)
@@ -639,7 +639,7 @@ static void draw_sphere_bone_dist(float smat[][4], float imat[][4], int boneflag
        
        /* figure out the sizes of spheres */
        if (ebone) {
-               /* this routine doesn't call set_matrix_editbone() that calculates it */
+               /* this routine doesn't call get_matrix_editbone() that calculates it */
                ebone->length = VecLenf(ebone->head, ebone->tail);
                
                length= ebone->length;
@@ -749,7 +749,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], int armflag,
        
        /* figure out the sizes of spheres */
        if (ebone) {
-               /* this routine doesn't call set_matrix_editbone() that calculates it */
+               /* this routine doesn't call get_matrix_editbone() that calculates it */
                ebone->length = VecLenf(ebone->head, ebone->tail);
                
                length= ebone->length;
@@ -1516,15 +1516,25 @@ static void draw_pose_dofs(Object *ob)
        }
 }
 
+static void bone_matrix_translate_y(float mat[][4], float y)
+{
+       float trans[3];
+
+       VECCOPY(trans, mat[1]);
+       VecMulf(trans, y);
+       VecAddf(mat[3], mat[3], trans);
+}
+
 /* assumes object is Armature with pose */
-static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
+static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt)
 {
+       RegionView3D *rv3d= ar->regiondata;
        Object *ob= base->object;
        bArmature *arm= ob->data;
        bPoseChannel *pchan;
        Bone *bone;
        GLfloat tmp;
-       float smat[4][4], imat[4][4];
+       float smat[4][4], imat[4][4], bmat[4][4];
        int index= -1;
        short do_dashed= 3, draw_wire= 0;
        short flag, constflag;
@@ -1809,15 +1819,21 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
                                                /*      Draw names of bone      */
                                                if (arm->flag & ARM_DRAWNAMES) {
                                                        VecMidf(vec, pchan->pose_head, pchan->pose_tail);
-                                                       view3d_object_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
+                                                       view3d_cached_text_draw_add(vec[0], vec[1], vec[2], pchan->name, 10);
                                                }       
                                                
                                                /*      Draw additional axes on the bone tail  */
                                                if ( (arm->flag & ARM_DRAWAXES) && (arm->flag & ARM_POSEMODE) ) {
                                                        glPushMatrix();
-                                                       glMultMatrixf(pchan->pose_mat);
-                                                       glTranslatef(0.0f, pchan->bone->length, 0.0f);
-                                                       drawaxes(0.25f*pchan->bone->length, 0, OB_ARROWS);
+                                                       Mat4CpyMat4(bmat, pchan->pose_mat);
+                                                       bone_matrix_translate_y(bmat, pchan->bone->length);
+                                                       glMultMatrixf(bmat);
+
+                                                       /* do cached text draw immediate to include transform */
+                                                       view3d_cached_text_draw_begin();
+                                                       drawaxes(pchan->bone->length*0.25f, 0, OB_ARROWS);
+                                                       view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
                                                        glPopMatrix();
                                                }
                                        }
@@ -1830,32 +1846,28 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, RegionView3D *rv3d, Ba
 }
 
 /* in editmode, we don't store the bone matrix... */
-static void set_matrix_editbone(EditBone *eBone)
+static void get_matrix_editbone(EditBone *eBone, float bmat[][4])
 {
-       float           delta[3],offset[3];
-       float           mat[3][3], bmat[4][4];
+       float           delta[3];
+       float           mat[3][3];
        
        /* Compose the parent transforms (i.e. their translations) */
-       VECCOPY(offset, eBone->head);
-       
-       glTranslatef(offset[0],offset[1],offset[2]);
-       
        VecSubf(delta, eBone->tail, eBone->head);       
        
        eBone->length = (float)sqrt(delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
        
        vec_roll_to_mat3(delta, eBone->roll, mat);
        Mat4CpyMat3(bmat, mat);
-               
-       glMultMatrixf(bmat);
-       
+
+       VecAddf(bmat[3], bmat[3], eBone->head);
 }
 
-static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
+static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
 {
+       RegionView3D *rv3d= ar->regiondata;
        EditBone *eBone;
        bArmature *arm= ob->data;
-       float smat[4][4], imat[4][4];
+       float smat[4][4], imat[4][4], bmat[4][4];
        unsigned int index;
        int flag;
        
@@ -1893,7 +1905,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
                        if (eBone->layer & arm->layer) {
                                if ((eBone->flag & BONE_HIDDEN_A)==0) {
                                        glPushMatrix();
-                                       set_matrix_editbone(eBone);
+                                       get_matrix_editbone(eBone, bmat);
+                                       glMultMatrixf(bmat);
                                        
                                        /* catch exception for bone with hidden parent */
                                        flag= eBone->flag;
@@ -1941,7 +1954,8 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
                                }
                                else {
                                        glPushMatrix();
-                                       set_matrix_editbone(eBone);
+                                       get_matrix_editbone(eBone, bmat);
+                                       glMultMatrixf(bmat);
                                        
                                        if (arm->drawtype == ARM_LINE) 
                                                draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
@@ -1994,14 +2008,20 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
                                                if (arm->flag & ARM_DRAWNAMES) {
                                                        VecMidf(vec, eBone->head, eBone->tail);
                                                        glRasterPos3fv(vec);
-                                                       view3d_object_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
+                                                       view3d_cached_text_draw_add(vec[0], vec[1], vec[2], eBone->name, 10);
                                                }                                       
                                                /*      Draw additional axes */
                                                if (arm->flag & ARM_DRAWAXES) {
                                                        glPushMatrix();
-                                                       set_matrix_editbone(eBone);
-                                                       glTranslatef(0.0f, eBone->length, 0.0f);
+                                                       get_matrix_editbone(eBone, bmat);
+                                                       bone_matrix_translate_y(bmat, eBone->length);
+                                                       glMultMatrixf(bmat);
+
+                                                       /* do cached text draw immediate to include transform */
+                                                       view3d_cached_text_draw_begin();
                                                        drawaxes(eBone->length*0.25f, 0, OB_ARROWS);
+                                                       view3d_cached_text_draw_end(v3d, ar, 1, bmat);
+
                                                        glPopMatrix();
                                                }
                                                
@@ -2021,8 +2041,9 @@ static void draw_ebones(View3D *v3d, RegionView3D *rv3d, Object *ob, int dt)
 /* draw bone paths
  *     - in view space 
  */
-static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+static void draw_pose_paths(Scene *scene, View3D *v3d, ARegion *ar, Object *ob)
 {
+       RegionView3D *rv3d= ar->regiondata;
        AnimData *adt= BKE_animdata_from_id(&ob->id);
        bArmature *arm= ob->data;
        bPoseChannel *pchan;
@@ -2155,12 +2176,12 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                                                /* only draw framenum if several consecutive highlighted points don't occur on same point */
                                                if (a == 0) {
                                                        sprintf(str, "%d", (a+sfra));
-                                                       view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+                                                       view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
                                                }
                                                else if ((a > stepsize) && (a < len-stepsize)) { 
                                                        if ((VecEqual(fp, fp-(stepsize*3))==0) || (VecEqual(fp, fp+(stepsize*3))==0)) {
                                                                sprintf(str, "%d", (a+sfra));
-                                                               view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+                                                               view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
                                                        }
                                                }
                                        }
@@ -2202,7 +2223,7 @@ static void draw_pose_paths(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                                                                        char str[32];
                                                                        
                                                                        sprintf(str, "%d", (a+sfra));
-                                                                       view3d_object_text_draw_add(fp[0], fp[1], fp[2], str, 0);
+                                                                       view3d_cached_text_draw_add(fp[0], fp[1], fp[2], str, 0);
                                                                }
                                                        }
                                                }
@@ -2253,7 +2274,7 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
 /* draw ghosts that occur within a frame range 
  *     note: object should be in posemode 
  */
-static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
 {
        Object *ob= base->object;
        AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2295,7 +2316,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
                
                BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
                where_is_pose(scene, ob);
-               draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+               draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
        }
        glDisable(GL_BLEND);
        if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2315,7 +2336,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, RegionView3D *rv3d
 /* draw ghosts on keyframes in action within range 
  *     - object should be in posemode 
  */
-static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
 {
        Object *ob= base->object;
        AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2374,7 +2395,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                
                BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
                where_is_pose(scene, ob);
-               draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+               draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
        }
        glDisable(GL_BLEND);
        if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2394,7 +2415,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, RegionView3D *rv3d,
 /* draw ghosts around current frame
  *     - object is supposed to be armature in posemode 
  */
-static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base)
+static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
 {
        Object *ob= base->object;
        AnimData *adt= BKE_animdata_from_id(&ob->id);
@@ -2444,7 +2465,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                        if (CFRA != cfrao) {
                                BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
                                where_is_pose(scene, ob);
-                               draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+                               draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
                        }
                }
                
@@ -2459,7 +2480,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
                        if (CFRA != cfrao) {
                                BKE_animsys_evaluate_animdata(&ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
                                where_is_pose(scene, ob);
-                               draw_pose_channels(scene, v3d, rv3d, base, OB_WIRE);
+                               draw_pose_channels(scene, v3d, ar, base, OB_WIRE);
                        }
                }
        }
@@ -2480,7 +2501,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
 /* ********************************** Armature Drawing - Main ************************* */
 
 /* called from drawobject.c, return 1 if nothing was drawn */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag)
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag)
 {
        Object *ob= base->object;
        bArmature *arm= ob->data;
@@ -2504,7 +2525,7 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
        /* editmode? */
        if(arm->edbo) {
                arm->flag |= ARM_EDITMODE;
-               draw_ebones(v3d, rv3d, ob, dt);
+               draw_ebones(v3d, ar, ob, dt);
                arm->flag &= ~ARM_EDITMODE;
        }
        else{
@@ -2522,14 +2543,14 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
                                }
                                else if(ob->mode & OB_MODE_POSE) {
                                        if (arm->ghosttype == ARM_GHOST_RANGE) {
-                                               draw_ghost_poses_range(scene, v3d, rv3d, base);
+                                               draw_ghost_poses_range(scene, v3d, ar, base);
                                        }
                                        else if (arm->ghosttype == ARM_GHOST_KEYS) {
-                                               draw_ghost_poses_keys(scene, v3d, rv3d, base);
+                                               draw_ghost_poses_keys(scene, v3d, ar, base);
                                        }
                                        else if (arm->ghosttype == ARM_GHOST_CUR) {
                                                if (arm->ghostep)
-                                                       draw_ghost_poses(scene, v3d, rv3d, base);
+                                                       draw_ghost_poses(scene, v3d, ar, base);
                                        }
                                        if ((flag & DRAW_SCENESET)==0) {
                                                if(ob==OBACT) 
@@ -2538,11 +2559,11 @@ int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int
                                                        if(ob==modifiers_isDeformedByArmature(OBACT))
                                                                arm->flag |= ARM_POSEMODE;
                                                }
-                                               draw_pose_paths(scene, v3d, rv3d, ob);
+                                               draw_pose_paths(scene, v3d, ar, ob);
                                        }
                                }       
                        }
-                       draw_pose_channels(scene, v3d, rv3d, base, dt);
+                       draw_pose_channels(scene, v3d, ar, base, dt);
                        arm->flag &= ~ARM_POSEMODE; 
                        
                        if(ob->mode & OB_MODE_POSE)
index b8852486dea401ee1633281268ac1aafb0ad882b..60ae91e7a897f3f4051b132ce7a58173a88a8242 100644 (file)
@@ -434,11 +434,11 @@ void drawaxes(float size, int flag, char drawtype)
                        // patch for 3d cards crashing on glSelect for text drawing (IBM)
                        if((flag & DRAW_PICKING) == 0) {
                                if (axis==0)
-                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
+                                       view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "x", 0);
                                else if (axis==1)
-                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
+                                       view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "y", 0);
                                else
-                                       view3d_object_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
+                                       view3d_cached_text_draw_add(v2[0], v2[1], v2[2], "z", 0);
                        }
                }
                break;
@@ -496,23 +496,32 @@ static void drawcentercircle(View3D *v3d, RegionView3D *rv3d, float *vec, int se
        if(v3d->zbuf)  glDepthFunc(GL_LEQUAL);
 }
 
-/* *********** text drawing for object ************* */
-static ListBase strings= {NULL, NULL};
+/* *********** text drawing for object/particles/armature ************* */
 
-typedef struct ViewObjectString {
-       struct ViewObjectString *next, *prev;
+static ListBase CachedText[3];
+static int CachedTextLevel= 0;
+
+typedef struct ViewCachedString {
+       struct ViewCachedString *next, *prev;
        float vec[3], col[4];
        char str[128]; 
        short mval[2];
        short xoffs;
-} ViewObjectString;
+} ViewCachedString;
 
+void view3d_cached_text_draw_begin()
+{
+       ListBase *strings= &CachedText[CachedTextLevel];
+       strings->first= strings->last= NULL;
+       CachedTextLevel++;
+}
 
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs)
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs)
 {
-       ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
+       ListBase *strings= &CachedText[CachedTextLevel-1];
+       ViewCachedString *vos= MEM_callocN(sizeof(ViewCachedString), "ViewCachedString");
 
-       BLI_addtail(&strings, vos);
+       BLI_addtail(strings, vos);
        BLI_strncpy(vos->str, str, 128);
        vos->vec[0]= x;
        vos->vec[1]= y;
@@ -521,22 +530,23 @@ void view3d_object_text_draw_add(float x, float y, float z, char *str, short xof
        vos->xoffs= xoffs;
 }
 
-static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4])
 {
-       ViewObjectString *vos;
-       int tot= 0;
+       RegionView3D *rv3d= ar->regiondata;
+       ListBase *strings= &CachedText[CachedTextLevel-1];
+       ViewCachedString *vos;
+       int a, tot= 0;
        
        /* project first and test */
-       for(vos= strings.first; vos; vos= vos->next) {
+       for(vos= strings->first; vos; vos= vos->next) {
+               if(mat)
+                       Mat4MulVecfl(mat, vos->vec);
                view3d_project_short_clip(ar, vos->vec, vos->mval);
                if(vos->mval[0]!=IS_CLIPPED)
                        tot++;
        }
-       
+
        if(tot) {
-               RegionView3D *rv3d= ar->regiondata;
-               int a;
-               
                if(rv3d->rflag & RV3D_CLIPPING)
                        for(a=0; a<6; a++)
                                glDisable(GL_CLIP_PLANE0+a);
@@ -544,16 +554,22 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
                wmPushMatrix();
                ED_region_pixelspace(ar);
                
-               if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+               if(depth_write) {
+                       if(v3d->zbuf) glDisable(GL_DEPTH_TEST);
+               }
+               else glDepthMask(0);
                
-               for(vos= strings.first; vos; vos= vos->next) {
+               for(vos= strings->first; vos; vos= vos->next) {
                        if(vos->mval[0]!=IS_CLIPPED) {
                                glColor3fv(vos->col);
-                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 0.0, vos->str);
+                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], (depth_write)? 0.0f: 2.0f, vos->str);
                        }
                }
                
-               if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+               if(depth_write) {
+                       if(v3d->zbuf) glEnable(GL_DEPTH_TEST);
+               }
+               else glDepthMask(1);
                
                wmPopMatrix();
 
@@ -562,10 +578,14 @@ static void view3d_object_text_draw(View3D *v3d, ARegion *ar)
                                glEnable(GL_CLIP_PLANE0+a);
        }
        
-       if(strings.first) 
-               BLI_freelistN(&strings);
+       if(strings->first) 
+               BLI_freelistN(strings);
+       
+       CachedTextLevel--;
 }
 
+/* ******************** primitive drawing ******************* */
+
 static void drawcube(void)
 {
 
@@ -1912,7 +1932,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val, conv_float, VecLenf(v1, v2));
                                
-                               view3d_object_text_draw_add(x, y, z, val, 0);
+                               view3d_cached_text_draw_add(x, y, z, val, 0);
                        }
                }
        }
@@ -1951,7 +1971,7 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val, conv_float, area);
 
-                               view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+                               view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
                        }
                }
        }
@@ -1993,13 +2013,13 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                /* Vec 1 */
                                sprintf(val,"%.3f", RAD2DEG(VecAngle3(v4, v1, v2)));
                                VecLerpf(fvec, efa->cent, efa->v1->co, 0.8f);
-                               view3d_object_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
+                               view3d_cached_text_draw_add(efa->cent[0], efa->cent[1], efa->cent[2], val, 0);
                        }
                        if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
                                /* Vec 2 */
                                sprintf(val,"%.3f", RAD2DEG(VecAngle3(v1, v2, v3)));
                                VecLerpf(fvec, efa->cent, efa->v2->co, 0.8f);
-                               view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+                               view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                        }
                        if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
                                /* Vec 3 */
@@ -2008,14 +2028,14 @@ static void draw_em_measure_stats(View3D *v3d, RegionView3D *rv3d, Object *ob, E
                                else
                                        sprintf(val,"%.3f", RAD2DEG(VecAngle3(v2, v3, v1)));
                                VecLerpf(fvec, efa->cent, efa->v3->co, 0.8f);
-                               view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+                               view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                        }
                                /* Vec 4 */
                        if(efa->v4) {
                                if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
                                        sprintf(val,"%.3f", RAD2DEG(VecAngle3(v3, v4, v1)));
                                        VecLerpf(fvec, efa->cent, efa->v4->co, 0.8f);
-                                       view3d_object_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
+                                       view3d_cached_text_draw_add(fvec[0], fvec[1], fvec[2], val, 0);
                                }
                        }
                }
@@ -2905,75 +2925,8 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
        return retval;
 }
 
-/* *********** text drawing for particles ************* */
-static ListBase pstrings= {NULL, NULL};
-
-typedef struct ViewParticleString {
-       struct ViewParticleString *next, *prev;
-       float vec[3], col[4];
-       char str[128]; 
-       short mval[2];
-       short xoffs;
-} ViewParticleString;
-
-
-void view3d_particle_text_draw_add(float x, float y, float z, char *str, short xoffs)
-{
-       ViewObjectString *vos= MEM_callocN(sizeof(ViewObjectString), "ViewObjectString");
-
-       BLI_addtail(&pstrings, vos);
-       BLI_strncpy(vos->str, str, 128);
-       vos->vec[0]= x;
-       vos->vec[1]= y;
-       vos->vec[2]= z;
-       glGetFloatv(GL_CURRENT_COLOR, vos->col);
-       vos->xoffs= xoffs;
-}
-
-static void view3d_particle_text_draw(View3D *v3d, ARegion *ar)
-{
-       ViewObjectString *vos;
-       int tot= 0;
-       
-       /* project first and test */
-       for(vos= pstrings.first; vos; vos= vos->next) {
-               project_short(ar, vos->vec, vos->mval);
-               if(vos->mval[0]!=IS_CLIPPED)
-                       tot++;
-       }
-       
-       if(tot) {
-               RegionView3D *rv3d= ar->regiondata;
-               int a;
-               
-               if(rv3d->rflag & RV3D_CLIPPING)
-                       for(a=0; a<6; a++)
-                               glDisable(GL_CLIP_PLANE0+a);
-               
-               wmPushMatrix();
-               ED_region_pixelspace(ar);
-               
-               if(v3d->zbuf) glDepthMask(0);
-
-               for(vos= pstrings.first; vos; vos= vos->next) {
-                       if(vos->mval[0]!=IS_CLIPPED) {
-                               glColor3fv(vos->col);
-                               BLF_draw_default((float)vos->mval[0]+vos->xoffs, (float)vos->mval[1], 2.0, vos->str);
-                       }
-               }
-               
-               if(v3d->zbuf) glDepthMask(1);
-               
-               wmPopMatrix();
+/* *********** drawing for particles ************* */
 
-               if(rv3d->rflag & RV3D_CLIPPING)
-                       for(a=0; a<6; a++)
-                               glEnable(GL_CLIP_PLANE0+a);
-       }
-       
-       if(pstrings.first) 
-               BLI_freelistN(&pstrings);
-}
 static void draw_particle(ParticleKey *state, int draw_as, short draw, float pixsize, float imat[4][4], float *draw_line, ParticleBillboardData *bb, ParticleDrawData *pdd)
 {
        float vec[3], vec2[3];
@@ -3540,7 +3493,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                                        sprintf(val, "%s %.2f", val, pa_health);
 
                                                /* in path drawing state.co is the end point */
-                                               view3d_particle_text_draw_add(state.co[0],  state.co[1],  state.co[2], val, 0);
+                                               view3d_cached_text_draw_add(state.co[0],  state.co[1],  state.co[2], val, 0);
                                        }
                                }
                        }
@@ -4755,8 +4708,9 @@ static void drawtexspace(Object *ob)
 }
 
 /* draws wire outline */
-static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base) 
+static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) 
 {
+       RegionView3D *rv3d= ar->regiondata;
        Object *ob= base->object;
        
        glLineWidth(2.0);
@@ -4775,7 +4729,7 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base
        }
        else if(ob->type==OB_ARMATURE) {
                if(!(ob->mode & OB_MODE_POSE))
-                       draw_armature(scene, v3d, rv3d, base, OB_WIRE, 0);
+                       draw_armature(scene, v3d, ar, base, OB_WIRE, 0);
        }
 
        glLineWidth(1.0);
@@ -4885,11 +4839,11 @@ void drawRBpivot(bRigidBodyJointConstraint *data)
                glVertex3fv(v);                 
                glEnd();
                if (axis==0)
-                       view3d_object_text_draw_add(v[0], v[1], v[2], "px", 0);
+                       view3d_cached_text_draw_add(v[0], v[1], v[2], "px", 0);
                else if (axis==1)
-                       view3d_object_text_draw_add(v[0], v[1], v[2], "py", 0);
+                       view3d_cached_text_draw_add(v[0], v[1], v[2], "py", 0);
                else
-                       view3d_object_text_draw_add(v[0], v[1], v[2], "pz", 0);
+                       view3d_cached_text_draw_add(v[0], v[1], v[2], "pz", 0);
        }
        glLineWidth (1.0f);
        setlinestyle(0);
@@ -4932,6 +4886,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                }
        }
 
+       /* no return after this point, otherwise leaks */
+       view3d_cached_text_draw_begin();
+
        /* draw keys? */
 #if 0 // XXX old animation system
        if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) {
@@ -5116,7 +5073,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=scene->obedit && (flag && DRAW_SCENESET)==0) {
                        if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(flag&DRAW_PICKING)) {
                                
-                               drawSolidSelect(scene, v3d, rv3d, base);
+                               drawSolidSelect(scene, v3d, ar, base);
                        }
                }
        }
@@ -5262,7 +5219,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        break;
                case OB_ARMATURE:
                        if(dt>OB_WIRE) GPU_enable_material(0, NULL); // we use default material
-                       empty_object= draw_armature(scene, v3d, rv3d, base, dt, flag);
+                       empty_object= draw_armature(scene, v3d, ar, base, dt, flag);
                        if(dt>OB_WIRE) GPU_disable_material();
                        break;
                default:
@@ -5282,10 +5239,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
 
                wmLoadMatrix(rv3d->viewmat);
                
+               view3d_cached_text_draw_begin();
+
                for(psys=ob->particlesystem.first; psys; psys=psys->next)
                        draw_new_particle_system(scene, v3d, rv3d, base, psys, dt);
                
-               view3d_particle_text_draw(v3d, ar);
+               view3d_cached_text_draw_end(v3d, ar, 0, NULL);
 
                wmMultMatrix(ob->obmat);
                
@@ -5437,7 +5396,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
                        /* patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing */
                        /* but, we also dont draw names for sets or duplicators */
                        if(flag == 0) {
-                               view3d_object_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
+                               view3d_cached_text_draw_add(0.0f, 0.0f, 0.0f, ob->id.name+2, 10);
                        }
                }
                /*if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/
@@ -5460,7 +5419,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
        }
        
        /* return warning, this is cached text draw */
-       view3d_object_text_draw(v3d, ar);
+       view3d_cached_text_draw_end(v3d, ar, 1, NULL);
 
        wmLoadMatrix(rv3d->viewmat);
 
index 7dbea44b68b3189d63594a8cb50496c0cb971036..52505fad521fa2b79b05e8fd11e7a71b7a9f3a08 100644 (file)
@@ -89,10 +89,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt);
 void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline);
 void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob);
 void drawaxes(float size, int flag, char drawtype);
-void view3d_object_text_draw_add(float x, float y, float z, char *str, short xoffs);
+
+void view3d_cached_text_draw_begin(void);
+void view3d_cached_text_draw_add(float x, float y, float z, char *str, short xoffs);
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, float mat[][4]);
 
 /* drawarmature.c */
-int draw_armature(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag);
+int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag);
 
 /* drawmesh.c */
 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, struct DerivedMesh *dm, int faceselect);