Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
index 5eb97630e83d16fd03ddde1018b2cd846e4b27bd..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"
@@ -650,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) 
 {
@@ -676,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) {
@@ -759,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);
@@ -795,7 +791,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
                                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) {
@@ -838,7 +834,7 @@ 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);
 }
@@ -984,9 +980,13 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
                                        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(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) {
@@ -1063,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);
 
@@ -1114,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]);
@@ -1161,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;
@@ -1205,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);
@@ -1253,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;
                                                }
                                        }
@@ -1262,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) {
@@ -1397,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;
@@ -1567,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;
@@ -1853,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)