Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
index 707bf95f9c3d494b721282ec4b2297fc349fc0d6..d130c7b40ac56fee8f6d0028bbd23072c598616c 100644 (file)
@@ -1,41 +1,39 @@
 /*
-* $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
  */
+
 #include "GL/glew.h"
 
 #include "BLI_blenlib.h"
@@ -756,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);
@@ -1352,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;
@@ -1522,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;