Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
index a7451a2ce807497b3e442f91036fdce7497639da..d130c7b40ac56fee8f6d0028bbd23072c598616c 100644 (file)
@@ -1,45 +1,40 @@
 /*
-* $Id$
-*
-* ***** BEGIN GPL LICENSE BLOCK *****
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software  Foundation,
-* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-* The Original Code is Copyright (C) 2006 Blender Foundation.
-* All rights reserved.
-*
-* The Original Code is: all of this file.
-*
-* Contributor(s): Ben Batt <benbatt@gmail.com>
-*
-* ***** END GPL LICENSE BLOCK *****
-*
-* Implementation of CDDerivedMesh.
-*
-* BKE_cdderivedmesh.h contains the function prototypes for this file.
-*
-*/
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software  Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Ben Batt <benbatt@gmail.com>
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Implementation of CDDerivedMesh.
+ *
+ * BKE_cdderivedmesh.h contains the function prototypes for this file.
+ *
+ */
 
 /** \file blender/blenkernel/intern/cdderivedmesh.c
  *  \ingroup bke
  */
 
-/* TODO maybe BIF_gl.h should include string.h? */
-#include <string.h>
-#include "BIF_gl.h"
+#include "GL/glew.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_edgehash.h"
@@ -268,33 +263,6 @@ static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
 
        BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
 }
-// Jason
-static void cdDM_drawSelectedVerts(DerivedMesh *dm)
-{
-       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
-       MVert *mv = cddm->mvert;
-       int i;
-       if( GPU_buffer_legacy(dm) ) {
-               glBegin(GL_POINTS);
-               for(i = 0; i < dm->numVertData; i++, mv++) {
-                       if(mv->flag & 1) {//TODO define selected
-                               glColor3f(1.0f, 1.0f, 0.0f);
-                       }else {
-                               glColor3f(0.0f, 0.0f, 0.0f);
-                       }
-                       glVertex3fv(mv->co);
-               }
-               glEnd();
-       }
-       else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
-               GPU_vertex_setup(dm);
-               if( !GPU_buffer_legacy(dm) ) {
-                       if(dm->drawObject->nelements)   glDrawArrays(GL_POINTS,0, dm->drawObject->nelements);
-                       else                                                    glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
-               }
-               GPU_buffer_unbind();
-       }
-}
 
 static void cdDM_drawVerts(DerivedMesh *dm)
 {
@@ -311,8 +279,10 @@ static void cdDM_drawVerts(DerivedMesh *dm)
        else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
                GPU_vertex_setup(dm);
                if( !GPU_buffer_legacy(dm) ) {
-                       if(dm->drawObject->nelements)   glDrawArrays(GL_POINTS,0, dm->drawObject->nelements);
-                       else                                                    glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
+                       if(dm->drawObject->tot_triangle_point)
+                               glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
+                       else
+                               glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
                }
                GPU_buffer_unbind();
        }
@@ -574,9 +544,10 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
                GPU_normal_setup( dm );
                if( !GPU_buffer_legacy(dm) ) {
                        glShadeModel(GL_SMOOTH);
-                       for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
+                       for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
                                if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
-                                       glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
+                                       glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
+                                                    dm->drawObject->materials[a].totpoint);
                        }
                }
                GPU_buffer_unbind( );
@@ -656,13 +627,13 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
                GPU_color_setup(dm);
                if( !GPU_buffer_legacy(dm) ) {
                        glShadeModel(GL_SMOOTH);
-                       glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
+                       glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
 
                        if( useTwoSided ) {
                                GPU_color4_upload(dm,cp2);
                                GPU_color_setup(dm);
                                glCullFace(GL_FRONT);
-                               glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
+                               glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
                                glCullFace(GL_BACK);
                        }
                }
@@ -674,7 +645,7 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
 }
 
 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
-                          int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
+                          int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
                           int (*drawParamsMapped)(void *userData, int index),
                           void *userData) 
 {
@@ -700,7 +671,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
                        unsigned char *cp = NULL;
 
                        if(drawParams) {
-                               flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr);
+                               flag = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
                        }
                        else {
                                if(index) {
@@ -783,9 +754,10 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
                                unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
                                for( i=0; i < dm->getNumFaces(dm); i++ ) {
                                        for( j=0; j < 4; j++ ) {
-                                               colors[i*12+j*3] = col[i*4+j].r;
+                                               /* bgr -> rgb is intentional (and stupid), but how its stored internally */
+                                               colors[i*12+j*3] = col[i*4+j].b;
                                                colors[i*12+j*3+1] = col[i*4+j].g;
-                                               colors[i*12+j*3+2] = col[i*4+j].b;
+                                               colors[i*12+j*3+2] = col[i*4+j].r;
                                        }
                                }
                                GPU_color3_upload(dm,colors);
@@ -814,12 +786,12 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
                        
                        glShadeModel( GL_SMOOTH );
                        lastFlag = 0;
-                       for(i = 0; i < dm->drawObject->nelements/3; i++) {
-                               int actualFace = dm->drawObject->faceRemap[i];
+                       for(i = 0; i < dm->drawObject->tot_triangle_point/3; i++) {
+                               int actualFace = dm->drawObject->triangle_to_mface[i];
                                int flag = 1;
 
                                if(drawParams) {
-                                       flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr);
+                                       flag = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
                                }
                                else {
                                        if(index) {
@@ -846,13 +818,13 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
                                        startFace = i;
                                }
                        }
-                       if( startFace < dm->drawObject->nelements/3 ) {
+                       if( startFace < dm->drawObject->tot_triangle_point/3 ) {
                                if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
                                        if (lastFlag==1 && col)
                                                GPU_color_switch(1);
                                        else
                                                GPU_color_switch(0);
-                                       glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
+                                       glDrawArrays(GL_TRIANGLES, startFace*3, dm->drawObject->tot_triangle_point - startFace*3);
                                }
                        }
                }
@@ -862,12 +834,13 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
        }
 }
 
-static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
+static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr))
 {
        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;
@@ -962,7 +935,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                if( useColors && mc )
                        GPU_color_setup(dm);
                if( !GPU_buffer_legacy(dm) ) {
-                       int tottri = dm->drawObject->nelements/3;
+                       int tottri = dm->drawObject->tot_triangle_point/3;
                        glShadeModel(GL_SMOOTH);
                        
                        if(tottri == 0) {
@@ -974,17 +947,18 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                        }
                        else {
                                /* we need to check if the next material changes */
-                               int next_actualFace= dm->drawObject->faceRemap[0];
+                               int next_actualFace= dm->drawObject->triangle_to_mface[0];
                                
                                for( i = 0; i < tottri; i++ ) {
-                                       //int actualFace = dm->drawObject->faceRemap[i];
+                                       //int actualFace = dm->drawObject->triangle_to_mface[i];
                                        int actualFace = next_actualFace;
                                        MFace *mface= mf + actualFace;
                                        int drawSmooth= (mface->flag & ME_SMOOTH);
                                        int draw = 1;
+                                       int flush = 0;
 
                                        if(i != tottri-1)
-                                               next_actualFace= dm->drawObject->faceRemap[i+1];
+                                               next_actualFace= dm->drawObject->triangle_to_mface[i+1];
 
                                        orig= (index==NULL) ? actualFace : index[actualFace];
 
@@ -996,11 +970,32 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                                        /* 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];
+
+                                               if(orig==ORIGINDEX_NONE || next_orig==ORIGINDEX_NONE) {
+                                                       flush= 1;
+                                               } else {
+                                                       /* 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;
                                        }
                                }
@@ -1017,6 +1012,50 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void
        cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
 }
 
+static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
+{
+       int b;
+
+       /* orco texture coordinates */
+       if(attribs->totorco) {
+               if(attribs->orco.glTexco)
+                       glTexCoord3fv(attribs->orco.array[index]);
+               else
+                       glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
+       }
+
+       /* uv texture coordinates */
+       for(b = 0; b < attribs->tottface; b++) {
+               MTFace *tf = &attribs->tface[b].array[a];
+
+               if(attribs->tface[b].glTexco)
+                       glTexCoord2fv(tf->uv[vert]);
+               else
+                       glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
+       }
+
+       /* vertex colors */
+       for(b = 0; b < attribs->totmcol; b++) {
+               MCol *cp = &attribs->mcol[b].array[a*4 + vert];
+               GLubyte col[4];
+               col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
+               glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
+       }
+
+       /* tangent for normal mapping */
+       if(attribs->tottang) {
+               float *tang = attribs->tang.array[a*4 + vert];
+               glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
+       }
+
+       /* vertex normal */
+       if(smoothnormal)
+               glNormal3sv(mvert[index].no);
+       
+       /* vertex coordinate */
+       glVertex3fv(mvert[index].co);
+}
+
 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
 {
        CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
@@ -1024,18 +1063,15 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
        DMVertexAttribs attribs;
        MVert *mvert = cddm->mvert;
        MFace *mface = cddm->mface;
-       MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
+       /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
        float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
        int a, b, dodraw, matnr, new_matnr;
-       int transp, new_transp, orig_transp;
        int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
 
        cdDM_update_normals_from_pbvh(dm);
 
        matnr = -1;
        dodraw = 0;
-       transp = GPU_get_material_blend_mode();
-       orig_transp = transp;
 
        glShadeModel(GL_SMOOTH);
 
@@ -1075,22 +1111,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                        continue;
                        }
 
-                       if(tf) {
-                               new_transp = tf[a].transp;
-
-                               if(new_transp != transp) {
-                                       glEnd();
-
-                                       if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
-                                               GPU_set_material_blend_mode(orig_transp);
-                                       else
-                                               GPU_set_material_blend_mode(new_transp);
-                                       transp = new_transp;
-
-                                       glBegin(GL_QUADS);
-                               }
-                       }
-
                        if(!smoothnormal) {
                                if(nors) {
                                        glNormal3fv(nors[a]);
@@ -1107,37 +1127,14 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                }
                        }
 
-#define PASSVERT(index, vert) {                                                                                                        \
-               if(attribs.totorco)                                                                                                                     \
-                       glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
-               for(b = 0; b < attribs.tottface; b++) {                                                                         \
-                       MTFace *tf = &attribs.tface[b].array[a];                                                                \
-                       glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
-               }                                                                                                                                                       \
-               for(b = 0; b < attribs.totmcol; b++) {                                                                          \
-                       MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
-                       GLubyte col[4];                                                                                                                 \
-                       col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
-                       glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
-               }                                                                                                                                                       \
-               if(attribs.tottang) {                                                                                                           \
-                       float *tang = attribs.tang.array[a*4 + vert];                                                   \
-                       glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
-               }                                                                                                                                                       \
-               if(smoothnormal)                                                                                                                        \
-                       glNormal3sv(mvert[index].no);                                                                                   \
-               glVertex3fv(mvert[index].co);                                                                                           \
-       }
+                       cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
+                       cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
+                       cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
 
-                       PASSVERT(mface->v1, 0);
-                       PASSVERT(mface->v2, 1);
-                       PASSVERT(mface->v3, 2);
                        if(mface->v4)
-                               PASSVERT(mface->v4, 3)
+                               cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
                        else
-                               PASSVERT(mface->v3, 2)
-
-#undef PASSVERT
+                               cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
                }
                glEnd();
        }
@@ -1145,7 +1142,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                GPUBuffer *buffer = NULL;
                char *varray = NULL;
                int numdata = 0, elementsize = 0, offset;
-               int start = 0, numfaces = 0, prevdraw = 0, curface = 0;
+               int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
                int i;
 
                MFace *mf = mface;
@@ -1156,9 +1153,9 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                GPU_normal_setup(dm);
 
                if( !GPU_buffer_legacy(dm) ) {
-                       for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
+                       for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
 
-                               a = dm->drawObject->faceRemap[i];
+                               a = dm->drawObject->triangle_to_mface[i];
 
                                mface = mf + a;
                                new_matnr = mface->mat_nr + 1;
@@ -1180,7 +1177,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
 
                                                        if( numdata != 0 ) {
 
-                                                               GPU_buffer_free(buffer, NULL);
+                                                               GPU_buffer_free(buffer);
 
                                                                buffer = NULL;
                                                        }
@@ -1189,7 +1186,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                        }
                                        numdata = 0;
                                        start = curface;
-                                       prevdraw = dodraw;
+                                       /* prevdraw = dodraw; */ /* UNUSED */
                                        dodraw = setMaterial(matnr = new_matnr, &gattribs);
                                        if(dodraw) {
                                                DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
@@ -1220,7 +1217,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                                }
                                                if( numdata != 0 ) {
                                                        elementsize = GPU_attrib_element_size( datatypes, numdata );
-                                                       buffer = GPU_buffer_alloc( elementsize*dm->drawObject->nelements, NULL );
+                                                       buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
                                                        if( buffer == NULL ) {
                                                                GPU_buffer_unbind();
                                                                dm->drawObject->legacy = 1;
@@ -1229,7 +1226,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                                        varray = GPU_buffer_lock_stream(buffer);
                                                        if( varray == NULL ) {
                                                                GPU_buffer_unbind();
-                                                               GPU_buffer_free(buffer, NULL);
+                                                               GPU_buffer_free(buffer);
                                                                dm->drawObject->legacy = 1;
                                                                return;
                                                        }
@@ -1237,7 +1234,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                                else {
                                                        /* if the buffer was set, dont use it again.
                                                         * prevdraw was assumed true but didnt run so set to false - [#21036] */
-                                                       prevdraw= 0;
+                                                       /* prevdraw= 0; */ /* UNUSED */
                                                        buffer= NULL;
                                                }
                                        }
@@ -1246,33 +1243,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                        continue;
                                }
 
-                               if(tf) {
-                                       new_transp = tf[a].transp;
-
-                                       if(new_transp != transp) {
-                                               numfaces = curface - start;
-                                               if( numfaces > 0 ) {
-                                                       if( dodraw ) {
-                                                               if( numdata != 0 ) {
-                                                                       GPU_buffer_unlock(buffer);
-                                                                       GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
-                                                               }
-                                                               glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
-                                                               if( numdata != 0 ) {
-                                                                       varray = GPU_buffer_lock_stream(buffer);
-                                                               }
-                                                       }
-                                               }
-                                               start = curface;
-
-                                               if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
-                                                       GPU_set_material_blend_mode(orig_transp);
-                                               else
-                                                       GPU_set_material_blend_mode(new_transp);
-                                               transp = new_transp;
-                                       }
-                               }
-                               
                                if( numdata != 0 ) {
                                        offset = 0;
                                        if(attribs.totorco) {
@@ -1311,6 +1281,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                                QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
                                                offset += sizeof(float)*4;
                                        }
+                                       (void)offset;
                                }
                                curface++;
                                if(mface->v4) {
@@ -1351,6 +1322,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                                                        QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
                                                        offset += sizeof(float)*4;
                                                }
+                                               (void)offset;
                                        }
                                        curface++;
                                        i++;
@@ -1368,7 +1340,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
                        }
                        GPU_buffer_unbind();
                }
-               GPU_buffer_free( buffer, NULL );
+               GPU_buffer_free(buffer);
        }
 
        glShadeModel(GL_FLAT);
@@ -1379,6 +1351,85 @@ static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at
        dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
 }
 
+static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
+       void (*setMaterial)(void *userData, int, void *attribs),
+       int (*setFace)(void *userData, int index), void *userData)
+{
+       CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+       GPUVertexAttribs gattribs;
+       DMVertexAttribs attribs;
+       MVert *mvert = cddm->mvert;
+       MFace *mf = cddm->mface;
+       float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
+       int a, matnr, new_matnr;
+       int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+
+       cdDM_update_normals_from_pbvh(dm);
+
+       matnr = -1;
+
+       glShadeModel(GL_SMOOTH);
+
+       memset(&attribs, 0, sizeof(attribs));
+
+       glBegin(GL_QUADS);
+
+       for(a = 0; a < dm->numFaceData; a++, mf++) {
+               const int smoothnormal = (mf->flag & ME_SMOOTH);
+
+               /* material */
+               new_matnr = mf->mat_nr + 1;
+
+               if(new_matnr != matnr) {
+                       glEnd();
+
+                       setMaterial(userData, matnr = new_matnr, &gattribs);
+                       DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+
+                       glBegin(GL_QUADS);
+               }
+
+               /* skipping faces */
+               if(setFace) {
+                       orig = (index)? index[a]: a;
+
+                       if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
+                               continue;
+               }
+
+               /* smooth normal */
+               if(!smoothnormal) {
+                       if(nors) {
+                               glNormal3fv(nors[a]);
+                       }
+                       else {
+                               /* TODO ideally a normal layer should always be available */
+                               float nor[3];
+
+                               if(mf->v4)
+                                       normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
+                               else
+                                       normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
+
+                               glNormal3fv(nor);
+                       }
+               }
+
+               /* vertices */
+               cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
+               cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
+               cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
+
+               if(mf->v4)
+                       cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
+               else
+                       cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
+       }
+       glEnd();
+
+       glShadeModel(GL_FLAT);
+}
+
 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
 {
        CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
@@ -1536,8 +1587,6 @@ static CDDerivedMesh *cdDM_create(const char *desc)
        dm->getFaceMap = cdDM_getFaceMap;
 
        dm->drawVerts = cdDM_drawVerts;
-       // Jason
-       dm->drawSelectedVerts = cdDM_drawSelectedVerts;
 
        dm->drawUVEdges = cdDM_drawUVEdges;
        dm->drawEdges = cdDM_drawEdges;
@@ -1551,6 +1600,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
        dm->drawMappedFaces = cdDM_drawMappedFaces;
        dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
        dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
+       dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
 
        dm->foreachMappedVert = cdDM_foreachMappedVert;
        dm->foreachMappedEdge = cdDM_foreachMappedEdge;
@@ -1837,7 +1887,7 @@ void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
        cddm->mvert = vert;
 
        for(i = 0; i < dm->numVertData; ++i, ++vert)
-               VECCOPY(vert->no, vertNormals[i]);
+               copy_v3_v3_short(vert->no, vertNormals[i]);
 }
 
 void CDDM_calc_normals(DerivedMesh *dm)