Texturing: texture and 3d view draw type changes, these should only have any
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Nov 2011 13:07:16 +0000 (13:07 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 Nov 2011 13:07:16 +0000 (13:07 +0000)
effect for a render engine using new shading nodes. In short:

* No longer uses images assigned to faces in the uv layer, rather the active
  image texture node is what is edited/painted/drawn.
* Textured draw type now shows the active image texture node, with solid
  lighting.
* Material draw mode shows GLSL shader of a simplified material node tree,
  using solid lighting.
* Textures for modifiers, brushes, etc, are now available from a dropdown in
  the texture tab in the properties editor. These do not use new shading nodes
  yet.

http://wiki.blender.org/index.php/Dev:2.6/Source/Render/TextureWorkflow

33 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/editors/include/ED_uvedit.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/mesh/mesh_data.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/space_buttons/CMakeLists.txt
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_buttons/buttons_intern.h
source/blender/editors/space_buttons/buttons_texture.c [new file with mode: 0644]
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/CMakeLists.txt
source/blender/editors/space_node/SConscript
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_templates.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/nodes/shader/node_shader_util.c
source/blenderplayer/bad_level_call_stubs/stubs.c

index 5e40384..0c5dc32 100644 (file)
@@ -324,6 +324,14 @@ struct DerivedMesh {
                                                                                                                           float t),
                                                                  void *userData);
 
+       /* Draw all faces with materials
+        *  o setMaterial is called for every different material nr
+        *  o setFace is called to verify if a face must be hidden
+        */
+       void (*drawMappedFacesMat)(DerivedMesh *dm,
+               void (*setMaterial)(void *userData, int, void *attribs),
+               int (*setFace)(void *userData, int index), void *userData);
+
        /* Release reference to the DerivedMesh. This function decides internally
         * if the DerivedMesh will be freed, or cached for later use. */
        void (*release)(DerivedMesh *dm);
index a06d57a..580f78d 100644 (file)
@@ -351,6 +351,7 @@ struct bNode        *nodeGetActive(struct bNodeTree *ntree);
 struct bNode   *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
 int                            nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id);
 void                   nodeClearActiveID(struct bNodeTree *ntree, short idtype);
+struct bNode   *nodeGetActiveTexture(struct bNodeTree *ntree);
 
 void                   nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
 int                            nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
index aaed038..ecabd1a 100644 (file)
@@ -1123,6 +1123,140 @@ static void emDM_drawFacesGLSL(DerivedMesh *dm,
        dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
 }
 
+static void emDM_drawMappedFacesMat(DerivedMesh *dm,
+                          void (*setMaterial)(void *userData, int, void *attribs),
+                          int (*setFace)(void *userData, int index), void *userData) 
+{
+       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+       EditMesh *em= emdm->em;
+       float (*vertexCos)[3]= emdm->vertexCos;
+       float (*vertexNos)[3]= emdm->vertexNos;
+       EditVert *eve;
+       EditFace *efa;
+       DMVertexAttribs attribs= {{{0}}};
+       GPUVertexAttribs gattribs;
+       int i, b, matnr, new_matnr;
+
+       matnr = -1;
+
+       /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
+       glShadeModel(GL_SMOOTH);
+
+       for (i=0,eve=em->verts.first; eve; eve= eve->next)
+               eve->tmp.l = (intptr_t) i++;
+
+#define PASSATTRIB(efa, eve, vert) {                                                                                   \
+       if(attribs.totorco) {                                                                                                           \
+               float *orco = attribs.orco.array[eve->tmp.l];                                                   \
+               if(attribs.orco.glTexco)                                                                                                \
+                       glTexCoord3fv(orco);                                                                                            \
+               else                                                                                                                                    \
+                       glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                       \
+       }                                                                                                                                                       \
+       for(b = 0; b < attribs.tottface; b++) {                                                                         \
+               MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
+               if(attribs.tface[b].glTexco)                                                                                    \
+                       glTexCoord2fv(_tf->uv[vert]);                                                                           \
+               else                                                                                                                                    \
+                       glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);          \
+       }                                                                                                                                                       \
+       for(b = 0; b < attribs.totmcol; b++) {                                                                          \
+               MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
+               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[i*4 + vert];                                                   \
+               glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
+       }                                                                                                                                                       \
+}
+
+       for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
+               int drawSmooth= (efa->flag & ME_SMOOTH);
+
+               /* face hiding */
+               if(setFace && !setFace(userData, i))
+                       continue;
+
+               /* material */
+               new_matnr = efa->mat_nr + 1;
+               if(new_matnr != matnr) {
+                       setMaterial(userData, matnr = new_matnr, &gattribs);
+                       DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+               }
+
+               /* face */
+               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+               if (!drawSmooth) {
+                       if(vertexCos) glNormal3fv(emdm->faceNos[i]);
+                       else glNormal3fv(efa->n);
+
+                       PASSATTRIB(efa, efa->v1, 0);
+                       if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+                       else glVertex3fv(efa->v1->co);
+
+                       PASSATTRIB(efa, efa->v2, 1);
+                       if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+                       else glVertex3fv(efa->v2->co);
+
+                       PASSATTRIB(efa, efa->v3, 2);
+                       if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+                       else glVertex3fv(efa->v3->co);
+
+                       if(efa->v4) {
+                               PASSATTRIB(efa, efa->v4, 3);
+                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                               else glVertex3fv(efa->v4->co);
+                       }
+               } else {
+                       PASSATTRIB(efa, efa->v1, 0);
+                       if(vertexCos) {
+                               glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
+                               glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
+                       }
+                       else {
+                               glNormal3fv(efa->v1->no);
+                               glVertex3fv(efa->v1->co);
+                       }
+
+                       PASSATTRIB(efa, efa->v2, 1);
+                       if(vertexCos) {
+                               glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
+                               glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
+                       }
+                       else {
+                               glNormal3fv(efa->v2->no);
+                               glVertex3fv(efa->v2->co);
+                       }
+
+                       PASSATTRIB(efa, efa->v3, 2);
+                       if(vertexCos) {
+                               glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
+                               glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
+                       }
+                       else {
+                               glNormal3fv(efa->v3->no);
+                               glVertex3fv(efa->v3->co);
+                       }
+
+                       if(efa->v4) {
+                               PASSATTRIB(efa, efa->v4, 3);
+                               if(vertexCos) {
+                                       glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
+                                       glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
+                               }
+                               else {
+                                       glNormal3fv(efa->v4->no);
+                                       glVertex3fv(efa->v4->co);
+                               }
+                       }
+               }
+               glEnd();
+       }
+#undef PASSATTRIB
+}
+
 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
@@ -1429,6 +1563,7 @@ DerivedMesh *editmesh_get_derived(EditMesh *em, float (*vertexCos)[3])
        emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
        emdm->dm.drawFacesTex = emDM_drawFacesTex;
        emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
+       emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
        emdm->dm.drawUVEdges = emDM_drawUVEdges;
 
        emdm->dm.release = emDM_release;
index d2c86a1..5ebdd1e 100644 (file)
@@ -1351,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;
@@ -1521,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;
index 9fc18c3..fa023d8 100644 (file)
@@ -1314,11 +1314,15 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
                        if(GS(node->id->name) == GS(tnode->id->name))
                                tnode->flag &= ~NODE_ACTIVE_ID;
                }
+               if(node->typeinfo->nclass == NODE_CLASS_TEXTURE)
+                       tnode->flag &= ~NODE_ACTIVE_TEXTURE;
        }
        
        node->flag |= NODE_ACTIVE;
        if(node->id)
                node->flag |= NODE_ACTIVE_ID;
+       if(node->typeinfo->nclass == NODE_CLASS_TEXTURE)
+               node->flag |= NODE_ACTIVE_TEXTURE;
 }
 
 /* use flags are not persistent yet, groups might need different tagging, so we do it each time
index 9848b27..da2245f 100644 (file)
@@ -1511,6 +1511,155 @@ static void ccgDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *a
        dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
 }
 
+       /* Only used by non-editmesh types */
+static void ccgDM_drawMappedFacesMat(DerivedMesh *dm, void (*setMaterial)(void *userData, int, void *attribs), int (*setFace)(void *userData, int index), void *userData) {
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
+       GPUVertexAttribs gattribs;
+       DMVertexAttribs attribs= {{{NULL}}};
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       int gridFaces = gridSize - 1;
+       int edgeSize = ccgSubSurf_getEdgeSize(ss);
+       char *faceFlags = ccgdm->faceFlags;
+       int a, b, i, numVerts, matnr, new_matnr, totface;
+
+       ccgdm_pbvh_update(ccgdm);
+
+       matnr = -1;
+
+#define PASSATTRIB(dx, dy, vert) {                                                                                             \
+       if(attribs.totorco) {                                                                                                           \
+               index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize);                 \
+               if(attribs.orco.glTexco)                                                                                                \
+                       glTexCoord3fv(attribs.orco.array[index]);                                                       \
+               else                                                                                                                                    \
+                       glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
+       }                                                                                                                                                       \
+       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]);           \
+       }                                                                                                                                                       \
+       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);                                               \
+       }                                                                                                                                                       \
+}
+
+       totface = ccgSubSurf_getNumFaces(ss);
+       for(a = 0, i = 0; i < totface; i++) {
+               CCGFace *f = ccgdm->faceMap[i].face;
+               int S, x, y, drawSmooth;
+               int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f));
+               int origIndex = ccgDM_getFaceMapIndex(ss, f);
+               
+               numVerts = ccgSubSurf_getFaceNumVerts(f);
+
+               /* get flags */
+               if(faceFlags) {
+                       drawSmooth = (faceFlags[index*2] & ME_SMOOTH);
+                       new_matnr= faceFlags[index*2 + 1] + 1;
+               }
+               else {
+                       drawSmooth = 1;
+                       new_matnr= 1;
+               }
+
+               /* material */
+               if(new_matnr != matnr) {
+                       setMaterial(userData, matnr = new_matnr, &gattribs);
+                       DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
+               }
+
+               /* face hiding */
+               if((setFace && (origIndex != ORIGINDEX_NONE) && !setFace(userData, origIndex))) {
+                       a += gridFaces*gridFaces*numVerts;
+                       continue;
+               }
+
+               /* draw face*/
+               glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
+               for (S=0; S<numVerts; S++) {
+                       DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
+                       DMGridData *vda, *vdb;
+
+                       if (drawSmooth) {
+                               for (y=0; y<gridFaces; y++) {
+                                       glBegin(GL_QUAD_STRIP);
+                                       for (x=0; x<gridFaces; x++) {
+                                               vda = &faceGridData[(y+0)*gridSize + x];
+                                               vdb = &faceGridData[(y+1)*gridSize + x];
+                                               
+                                               PASSATTRIB(0, 0, 0);
+                                               glNormal3fv(vda->no);
+                                               glVertex3fv(vda->co);
+
+                                               PASSATTRIB(0, 1, 1);
+                                               glNormal3fv(vdb->no);
+                                               glVertex3fv(vdb->co);
+
+                                               if(x != gridFaces-1)
+                                                       a++;
+                                       }
+
+                                       vda = &faceGridData[(y+0)*gridSize + x];
+                                       vdb = &faceGridData[(y+1)*gridSize + x];
+
+                                       PASSATTRIB(0, 0, 3);
+                                       glNormal3fv(vda->no);
+                                       glVertex3fv(vda->co);
+
+                                       PASSATTRIB(0, 1, 2);
+                                       glNormal3fv(vdb->no);
+                                       glVertex3fv(vdb->co);
+
+                                       glEnd();
+
+                                       a++;
+                               }
+                       } else {
+                               glBegin(GL_QUADS);
+                               for (y=0; y<gridFaces; y++) {
+                                       for (x=0; x<gridFaces; x++) {
+                                               float *aco = faceGridData[(y+0)*gridSize + x].co;
+                                               float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
+                                               float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
+                                               float *dco = faceGridData[(y+1)*gridSize + x].co;
+
+                                               ccgDM_glNormalFast(aco, bco, cco, dco);
+
+                                               PASSATTRIB(0, 1, 1);
+                                               glVertex3fv(dco);
+                                               PASSATTRIB(1, 1, 2);
+                                               glVertex3fv(cco);
+                                               PASSATTRIB(1, 0, 3);
+                                               glVertex3fv(bco);
+                                               PASSATTRIB(0, 0, 0);
+                                               glVertex3fv(aco);
+                                               
+                                               a++;
+                                       }
+                               }
+                               glEnd();
+                       }
+               }
+       }
+
+#undef PASSATTRIB
+
+       ccgFaceIterator_free(fi);
+}
+
+
 static void ccgDM_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
@@ -2382,6 +2531,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
        ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
        ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
        ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
+       ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
        ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
 
        ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
index 2b4c213..0666884 100644 (file)
 struct ARegionType;
 struct EditFace;
 struct Image;
+struct Main;
+struct ImageUser;
 struct MTFace;
 struct Object;
 struct Scene;
+struct SpaceImage;
 struct bContext;
+struct bNode;
 struct wmKeyConfig;
 
 /* uvedit_ops.c */
 void ED_operatortypes_uvedit(void);
 void ED_keymap_uvedit(struct wmKeyConfig *keyconf);
 
-void ED_uvedit_assign_image(struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
+void ED_uvedit_assign_image(struct Main *bmain, struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma);
 int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float *min, float *max);
 
+int ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **ima, struct ImageUser **iuser, struct bNode **node);
+void ED_object_assign_active_image(struct Main *bmain, struct Object *ob, int mat_nr, struct Image *ima);
+
 int ED_uvedit_test_silent(struct Object *obedit);
 int ED_uvedit_test(struct Object *obedit);
 
index 02b8cc9..329f459 100644 (file)
@@ -758,6 +758,8 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr);
 void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type);
 void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
 void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input);
+void uiTemplateTextureUser(uiLayout *layout, struct bContext *C);
+void uiTemplateTextureShow(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop);
 
 void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact);
 void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname);
index 7c745c3..a3d7167 100644 (file)
@@ -332,7 +332,7 @@ static const char *template_id_browse_tip(StructRNA *type)
        return N_("Browse ID data to be linked");
 }
 
-static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, int flag, const char *newop, const char *openop, const char *unlinkop)
+static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, StructRNA *type, short idcode, int flag, const char *newop, const char *openop, const char *unlinkop)
 {
        uiBut *but;
        uiBlock *block;
@@ -478,6 +478,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
                if((idfrom && idfrom->lib) || !editable)
                        uiButSetFlag(but, UI_BUT_DISABLED);
        }
+
+       if(idcode == ID_TE)
+               uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
        
        uiBlockEndAlign(block);
 }
@@ -487,6 +490,7 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
        TemplateID *template;
        PropertyRNA *prop;
        StructRNA *type;
+       short idcode;
 
        prop= RNA_struct_find_property(ptr, propname);
 
@@ -507,14 +511,15 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
                flag |= UI_ID_OPEN;
 
        type= RNA_property_pointer_type(ptr, prop);
-       template->idlb= which_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
+       idcode= RNA_type_to_ID_code(type);
+       template->idlb= which_libbase(CTX_data_main(C), idcode);
        
        /* create UI elements for this template
         *      - template_ID makes a copy of the template data and assigns it to the relevant buttons
         */
        if(template->idlb) {
                uiLayoutRow(layout, 1);
-               template_ID(C, layout, template, type, flag, newop, openop, unlinkop);
+               template_ID(C, layout, template, type, idcode, flag, newop, openop, unlinkop);
        }
 
        MEM_freeN(template);
index ed890fd..6e35865 100644 (file)
@@ -51,6 +51,7 @@
 #include "BKE_displist.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
+#include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_report.h"
@@ -331,6 +332,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
 
 static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+       Main *bmain= CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        View3D *v3d= CTX_wm_view3d(C);
        Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
@@ -375,7 +377,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
        if(me->edit_mesh==NULL)
                return OPERATOR_CANCELLED;
        
-       ED_uvedit_assign_image(scene, obedit, ima, NULL);
+       ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
 
        if(exitmode) {
                load_editMesh(scene, obedit);
index ce603ce..e283927 100644 (file)
@@ -79,6 +79,7 @@
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_report.h"
+#include "BKE_scene.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -88,6 +89,7 @@
 #include "ED_image.h"
 #include "ED_screen.h"
 #include "ED_sculpt.h"
+#include "ED_uvedit.h"
 #include "ED_view3d.h"
 
 #include "WM_api.h"
@@ -498,6 +500,40 @@ static void image_undo_free(ListBase *lb)
                MEM_freeN(tile->rect);
 }
 
+/* get active image for face depending on old/new shading system */
+
+static Image *imapaint_face_image(const ImagePaintState *s, int face_index)
+{
+       Image *ima;
+
+       if(scene_use_new_shading_nodes(s->scene)) {
+               MFace *mf = s->me->mface+face_index;
+               ED_object_get_active_image(s->ob, mf->mat_nr, &ima, NULL, NULL);
+       }
+       else {
+               MTFace *tf = s->me->mtface+face_index;
+               ima = tf->tpage;
+       }
+
+       return ima;
+}
+
+static Image *project_paint_face_image(const ProjPaintState *ps, int face_index)
+{
+       Image *ima;
+
+       if(scene_use_new_shading_nodes(ps->scene)) {
+               MFace *mf = ps->dm_mface+face_index;
+               ED_object_get_active_image(ps->ob, mf->mat_nr, &ima, NULL, NULL);
+       }
+       else {
+               MTFace *tf = ps->dm_mtface+face_index;
+               ima = tf->tpage;
+       }
+
+       return ima;
+}
+
 /* fast projection bucket array lookup, use the safe version for bound checking  */
 static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
 {
@@ -670,6 +706,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float
        int side;
        int face_index;
        MTFace *tf;
+       Image *ima;
        ImBuf *ibuf;
        int xi, yi;
        
@@ -687,8 +724,9 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float
        else { /* QUAD */
                interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
        }
-       
-       ibuf = tf->tpage->ibufs.first; /* we must have got the imbuf before getting here */
+
+       ima = project_paint_face_image(ps, face_index);
+       ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
        if (!ibuf) return 0;
        
        if (interp) {
@@ -1053,6 +1091,9 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o
                        
                        /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
                        if (i2_fidx != -1) {
+                               Image *tpage = project_paint_face_image(ps, face_index);
+                               Image *orig_tpage = project_paint_face_image(ps, orig_face);
+
                                /* This IS an adjacent face!, now lets check if the UVs are ok */
                                tf = ps->dm_mtface + face_index;
                                
@@ -1061,7 +1102,7 @@ static int check_seam(const ProjPaintState *ps, const int orig_face, const int o
                                *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
                                
                                /* first test if they have the same image */
-                               if (    (orig_tf->tpage == tf->tpage) &&
+                               if (    (orig_tpage == tpage) &&
                                                cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
                                                cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
                                {
@@ -1308,9 +1349,10 @@ static float project_paint_uvpixel_mask(
        if (ps->do_layer_stencil) {
                /* another UV layers image is masking this one's */
                ImBuf *ibuf_other;
+               Image *other_tpage = project_paint_face_image(ps, face_index);
                const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
                
-               if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) {
+               if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
                        /* BKE_image_get_ibuf - TODO - this may be slow */
                        unsigned char rgba_ub[4];
                        float rgba_f[4];
@@ -1464,9 +1506,10 @@ static ProjPixel *project_paint_uvpixel_init(
        if (ps->tool==PAINT_TOOL_CLONE) {
                if (ps->dm_mtface_clone) {
                        ImBuf *ibuf_other;
+                       Image *other_tpage = project_paint_face_image(ps, face_index);
                        const MTFace *tf_other = ps->dm_mtface_clone + face_index;
                        
-                       if (tf_other->tpage && (ibuf_other = BKE_image_get_ibuf(tf_other->tpage, NULL))) {
+                       if (other_tpage && (ibuf_other = BKE_image_get_ibuf(other_tpage, NULL))) {
                                /* BKE_image_get_ibuf - TODO - this may be slow */
                                
                                if (ibuf->rect_float) {
@@ -2684,11 +2727,8 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
        LinkNode *node;
        int face_index, image_index=0;
        ImBuf *ibuf = NULL;
+       Image *tpage_last = NULL, *tpage;
        Image *ima = NULL;
-       MTFace *tf;
-       
-       Image *tpage_last = NULL;
-       
 
        if (ps->image_tot==1) {
                /* Simple loop, no context switching */
@@ -2706,9 +2746,9 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
                        face_index = GET_INT_FROM_POINTER(node->link);
                                
                        /* Image context switching */
-                       tf = ps->dm_mtface+face_index;
-                       if (tpage_last != tf->tpage) {
-                               tpage_last = tf->tpage;
+                       tpage = project_paint_face_image(ps, face_index);
+                       if (tpage_last != tpage) {
+                               tpage_last = tpage;
 
                                for (image_index=0; image_index < ps->image_tot; image_index++) {
                                        if (ps->projImages[image_index].ima == tpage_last) {
@@ -2876,7 +2916,7 @@ static void project_paint_begin(ProjPaintState *ps)
        LinkNode *node;
        
        ProjPaintImage *projIma;
-       Image *tpage_last = NULL;
+       Image *tpage_last = NULL, *tpage;
        
        /* Face vars */
        MFace *mf;
@@ -3210,7 +3250,9 @@ static void project_paint_begin(ProjPaintState *ps)
                }
 #endif
                
-               if (tf->tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK)==0 || mf->flag & ME_FACE_SEL)) {
+               tpage = project_paint_face_image(ps, face_index);
+
+               if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_MASK)==0 || mf->flag & ME_FACE_SEL)) {
                        
                        float *v1coSS, *v2coSS, *v3coSS, *v4coSS=NULL;
                        
@@ -3283,17 +3325,17 @@ static void project_paint_begin(ProjPaintState *ps)
                                }
                        }
                        
-                       if (tpage_last != tf->tpage) {
+                       if (tpage_last != tpage) {
                                
-                               image_index = BLI_linklist_index(image_LinkList, tf->tpage);
+                               image_index = BLI_linklist_index(image_LinkList, tpage);
                                
-                               if (image_index==-1 && BKE_image_get_ibuf(tf->tpage, NULL)) { /* MemArena dosnt have an append func */
-                                       BLI_linklist_append(&image_LinkList, tf->tpage);
+                               if (image_index==-1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
+                                       BLI_linklist_append(&image_LinkList, tpage);
                                        image_index = ps->image_tot;
                                        ps->image_tot++;
                                }
                                
-                               tpage_last = tf->tpage;
+                               tpage_last = tpage;
                        }
                        
                        if (image_index != -1) {
@@ -4481,7 +4523,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
                ) {
                        ImBuf *ibuf;
                        
-                       newimage = (s->me->mtface+newfaceindex)->tpage;
+                       newimage = imapaint_face_image(s, newfaceindex);
                        ibuf= BKE_image_get_ibuf(newimage, s->sima? &s->sima->iuser: NULL);
 
                        if(ibuf && ibuf->rect)
index dbb96b6..ee118f1 100644 (file)
@@ -38,6 +38,7 @@ set(SRC
        buttons_context.c
        buttons_header.c
        buttons_ops.c
+       buttons_texture.c
        space_buttons.c
 
        buttons_intern.h
index 6d6f73e..e38ac7b 100644 (file)
@@ -54,7 +54,6 @@
 #include "BKE_screen.h"
 #include "BKE_texture.h"
 
-
 #include "RNA_access.h"
 
 #include "ED_armature.h"
 
 #include "buttons_intern.h"    // own include
 
-typedef struct ButsContextPath {
-       PointerRNA ptr[8];
-       int len;
-       int flag;
-       int tex_ctx;
-} ButsContextPath;
-
 static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type)
 {
        PointerRNA *ptr;
@@ -373,102 +365,141 @@ static int buttons_context_path_brush(ButsContextPath *path)
        return 0;
 }
 
-static int buttons_context_path_texture(ButsContextPath *path)
+static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct)
 {
-       Material *ma;
-       Lamp *la;
-       Brush *br;
-       World *wo;
-       ParticleSystem *psys;
-       Tex *tex;
-       PointerRNA *ptr= &path->ptr[path->len-1];
-       int orig_len = path->len;
+       if(ct) {
+               /* new shading system */
+               PointerRNA *ptr= &path->ptr[path->len-1];
+               ID *id;
 
-       /* if we already have a (pinned) texture, we're done */
-       if(RNA_struct_is_a(ptr->type, &RNA_Texture)) {
-               return 1;
-       }
-       /* try brush */
-       if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) {
-               br= path->ptr[path->len-1].data;
-               
-               if(br) {
-                       tex= give_current_brush_texture(br);
+               /* if we already have a (pinned) texture, we're done */
+               if(RNA_struct_is_a(ptr->type, &RNA_Texture))
+                       return 1;
 
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+               if(!ct->user)
+                       return 0;
+               
+               id= ct->user->id;
+
+               if(id) {
+                       if(GS(id->name) == ID_BR)
+                               buttons_context_path_brush(path);
+                       else if(GS(id->name) == ID_MA)
+                               buttons_context_path_material(path, 0);
+                       else if(GS(id->name) == ID_WO)
+                               buttons_context_path_world(path);
+                       else if(GS(id->name) == ID_LA)
+                               buttons_context_path_data(path, OB_LAMP);
+                       else if(GS(id->name) == ID_PA)
+                               buttons_context_path_particle(path);
+                       else if(GS(id->name) == ID_OB)
+                               buttons_context_path_object(path);
+               }
+               
+               if(ct->texture) {
+                       RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]);
                        path->len++;
-                       return 1;
                }
-       }
-       /* try world */
-       if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
-               wo= path->ptr[path->len-1].data;
-
-               if(wo && GS(wo->id.name)==ID_WO) {
-                       tex= give_current_world_texture(wo);
 
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                       path->len++;
+               return 1;
+       }
+       else {
+               /* old shading system */
+               Material *ma;
+               Lamp *la;
+               Brush *br;
+               World *wo;
+               ParticleSystem *psys;
+               Tex *tex;
+               PointerRNA *ptr= &path->ptr[path->len-1];
+               int orig_len = path->len;
+
+               /* if we already have a (pinned) texture, we're done */
+               if(RNA_struct_is_a(ptr->type, &RNA_Texture)) {
                        return 1;
                }
-       }
-       /* try particles */
-       if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
-               if(path->ptr[path->len-1].type == &RNA_ParticleSettings) {
-                       ParticleSettings *part = path->ptr[path->len-1].data;
+               /* try brush */
+               if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) {
+                       br= path->ptr[path->len-1].data;
+                       
+                       if(br) {
+                               tex= give_current_brush_texture(br);
 
-                       tex= give_current_particle_texture(part);
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                       path->len++;
-                       return 1;
+                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
+                       }
                }
-               else {
-                       psys= path->ptr[path->len-1].data;
+               /* try world */
+               if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
+                       wo= path->ptr[path->len-1].data;
 
-                       if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
-                               tex= give_current_particle_texture(psys->part);
+                       if(wo && GS(wo->id.name)==ID_WO) {
+                               tex= give_current_world_texture(wo);
 
                                RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
                                path->len++;
                                return 1;
                        }
                }
-       }
-       /* try material */
-       if(buttons_context_path_material(path, 1)) {
-               ma= path->ptr[path->len-1].data;
+               /* try particles */
+               if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
+                       if(path->ptr[path->len-1].type == &RNA_ParticleSettings) {
+                               ParticleSettings *part = path->ptr[path->len-1].data;
 
-               if(ma) {
-                       tex= give_current_material_texture(ma);
+                               tex= give_current_particle_texture(part);
+                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
+                       }
+                       else {
+                               psys= path->ptr[path->len-1].data;
 
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                       path->len++;
-                       return 1;
+                               if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
+                                       tex= give_current_particle_texture(psys->part);
+
+                                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                                       path->len++;
+                                       return 1;
+                               }
+                       }
                }
-       }
-       /* try lamp */
-       if(buttons_context_path_data(path, OB_LAMP)) {
-               la= path->ptr[path->len-1].data;
+               /* try material */
+               if(buttons_context_path_material(path, 1)) {
+                       ma= path->ptr[path->len-1].data;
 
-               if(la) {
-                       tex= give_current_lamp_texture(la);
+                       if(ma) {
+                               tex= give_current_material_texture(ma);
 
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                       path->len++;
-                       return 1;
+                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
+                       }
                }
-       }
-       /* try brushes again in case of no material, lamp, etc */
-       path->len = orig_len;
-       if(buttons_context_path_brush(path)) {
-               br= path->ptr[path->len-1].data;
-               
-               if(br) {
-                       tex= give_current_brush_texture(br);
+               /* try lamp */
+               if(buttons_context_path_data(path, OB_LAMP)) {
+                       la= path->ptr[path->len-1].data;
+
+                       if(la) {
+                               tex= give_current_lamp_texture(la);
+
+                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
+                       }
+               }
+               /* try brushes again in case of no material, lamp, etc */
+               path->len = orig_len;
+               if(buttons_context_path_brush(path)) {
+                       br= path->ptr[path->len-1].data;
                        
-                       RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
-                       path->len++;
-                       return 1;
+                       if(br) {
+                               tex= give_current_brush_texture(br);
+                               
+                               RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
+                       }
                }
        }
 
@@ -530,7 +561,7 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
                        found= buttons_context_path_material(path, 0);
                        break;
                case BCONTEXT_TEXTURE:
-                       found= buttons_context_path_texture(path);
+                       found= buttons_context_path_texture(path, sbuts->texuser);
                        break;
                case BCONTEXT_BONE:
                        found= buttons_context_path_bone(path);
@@ -580,6 +611,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
        PointerRNA *ptr;
        int a, pflag= 0, flag= 0;
 
+       buttons_texture_context_compute(C, sbuts);
+
        if(!sbuts->path)
                sbuts->path= MEM_callocN(sizeof(ButsContextPath), "ButsContextPath");
        
@@ -649,7 +682,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
 const char *buttons_context_dir[] = {
        "world", "object", "mesh", "armature", "lattice", "curve",
        "meta_ball", "lamp", "speaker", "camera", "material", "material_slot",
-       "texture", "texture_slot", "bone", "edit_bone", "pose_bone", "particle_system", "particle_system_editable",
+       "texture", "texture_slot", "texture_user", "bone", "edit_bone",
+       "pose_bone", "particle_system", "particle_system_editable",
        "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
 
 int buttons_context(const bContext *C, const char *member, bContextDataResult *result)
@@ -710,7 +744,17 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
                return 1;
        }
        else if(CTX_data_equals(member, "texture")) {
-               set_pointer_type(path, result, &RNA_Texture);
+               ButsContextTexture *ct= sbuts->texuser;
+
+               if(ct) {
+                       /* new shading system */
+                       CTX_data_pointer_set(result, &ct->texture->id, &RNA_Texture, ct->texture);
+               }
+               else {
+                       /* old shading system */
+                       set_pointer_type(path, result, &RNA_Texture);
+               }
+
                return 1;
        }
        else if(CTX_data_equals(member, "material_slot")) {
@@ -729,23 +773,52 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
 
                return 1;
        }
-       else if(CTX_data_equals(member, "texture_node")) {
-               PointerRNA *ptr;
+       else if(CTX_data_equals(member, "texture_user")) {
+               ButsContextTexture *ct= sbuts->texuser;
 
-               if((ptr=get_pointer_type(path, &RNA_Material))) {
-                       Material *ma= ptr->data;
+               if(!ct)
+                       return 0; /* old shading system */
 
-                       if(ma) {
-                               bNode *node= give_current_material_texture_node(ma);
-                               CTX_data_pointer_set(result, &ma->id, &RNA_Node, node);
-                       }
+               if(ct->user && ct->user->ptr.data) {
+                       ButsTextureUser *user= ct->user; 
+                       CTX_data_pointer_set(result, user->ptr.id.data, user->ptr.type, user->ptr.data);
                }
 
                return 1;
        }
+       else if(CTX_data_equals(member, "texture_node")) {
+               ButsContextTexture *ct= sbuts->texuser;
+
+               if(ct) {
+                       /* new shading system */
+                       if(ct->user && ct->user->node)
+                               CTX_data_pointer_set(result, &ct->user->ntree->id, &RNA_Node, ct->user->node);
+
+                       return 1;
+               }
+               else {
+                       /* old shading system */
+                       PointerRNA *ptr;
+
+                       if((ptr=get_pointer_type(path, &RNA_Material))) {
+                               Material *ma= ptr->data;
+
+                               if(ma) {
+                                       bNode *node= give_current_material_texture_node(ma);
+                                       CTX_data_pointer_set(result, &ma->id, &RNA_Node, node);
+                               }
+                       }
+
+                       return 1;
+               }
+       }
        else if(CTX_data_equals(member, "texture_slot")) {
+               ButsContextTexture *ct= sbuts->texuser;
                PointerRNA *ptr;
 
+               if(ct)
+                       return 0; /* new shading system */
+
                if((ptr=get_pointer_type(path, &RNA_Material))) {
                        Material *ma= ptr->data;
 
index 2708448..aa692a9 100644 (file)
 #ifndef ED_BUTTONS_INTERN_H
 #define ED_BUTTONS_INTERN_H
 
+#include "DNA_listBase.h"
+#include "RNA_types.h"
+
 struct ARegion;
 struct ARegionType;
+struct ID;
+struct SpaceButs;
+struct Tex;
 struct bContext;
 struct bContextDataResult;
-struct SpaceButs;
+struct bNode;
+struct bNodeTree;
 struct uiLayout;
 struct wmOperatorType;
-struct ID;
 
 /* buts->scaflag */            
 #define BUTS_SENS_SEL          1
@@ -53,6 +59,42 @@ struct ID;
 #define BUTS_SENS_STATE                512
 #define BUTS_ACT_STATE         1024
 
+/* context data */
+
+typedef struct ButsContextPath {
+       PointerRNA ptr[8];
+       int len;
+       int flag;
+       int tex_ctx;
+} ButsContextPath;
+
+typedef struct ButsTextureUser {
+       struct ButsTextureUser *next, *prev;
+
+       struct ID *id;
+
+       PointerRNA ptr;
+       PropertyRNA *prop;
+
+       struct bNodeTree *ntree;
+       struct bNode *node;
+
+       const char *category;
+       int icon;
+       const char *name;
+
+       int index;
+} ButsTextureUser;
+
+typedef struct ButsContextTexture {
+       ListBase users;
+
+       struct Tex *texture;
+
+       struct ButsTextureUser *user;
+       int index;
+} ButsContextTexture;
+
 /* internal exports only */
 
 /* buttons_header.c */
@@ -67,6 +109,9 @@ struct ID *buttons_context_id_path(const struct bContext *C);
 
 extern const char *buttons_context_dir[]; /* doc access */
 
+/* buttons_texture.c */
+void buttons_texture_context_compute(const struct bContext *C, struct SpaceButs *sbuts);
+
 /* buttons_ops.c */
 void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
 void BUTTONS_OT_directory_browse(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
new file mode 100644 (file)
index 0000000..dd9f3c5
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * $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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_buttons/buttons_texture.c
+ *  \ingroup spbuttons
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_ID.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+#include "DNA_object_force.h"
+#include "DNA_particle_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_world_types.h"
+
+#include "BKE_context.h"
+#include "BKE_material.h"
+#include "BKE_modifier.h"
+#include "BKE_node.h"
+#include "BKE_paint.h"
+#include "BKE_particle.h"
+#include "BKE_scene.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "ED_node.h"
+#include "ED_screen.h"
+
+#include "../interface/interface_intern.h"
+
+#include "buttons_intern.h"    // own include
+
+/************************* Texture User **************************/
+
+static void buttons_texture_user_property_add(ListBase *users, ID *id, 
+       PointerRNA ptr, PropertyRNA *prop,
+       const char *category, int icon, const char *name)
+{
+       ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser");
+
+       user->id= id;
+       user->ptr = ptr;
+       user->prop = prop;
+       user->category = category;
+       user->icon = icon;
+       user->name = name;
+       user->index = BLI_countlist(users);
+
+       BLI_addtail(users, user);
+}
+
+static void buttons_texture_user_node_add(ListBase *users, ID *id, 
+       bNodeTree *ntree, bNode *node,
+       const char *category, int icon, const char *name)
+{
+       ButsTextureUser *user = MEM_callocN(sizeof(ButsTextureUser), "ButsTextureUser");
+
+       user->id= id;
+       user->ntree = ntree;
+       user->node = node;
+       user->category = category;
+       user->icon = icon;
+       user->name = name;
+       user->index = BLI_countlist(users);
+
+       BLI_addtail(users, user);
+}
+
+static void buttons_texture_users_find_nodetree(ListBase *users, ID *id,
+       bNodeTree *ntree, const char *category)
+{
+       bNode *node;
+
+       if(ntree) {
+               for(node=ntree->nodes.first; node; node=node->next) {
+                       if(node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
+                               PointerRNA ptr;
+                               PropertyRNA *prop;
+
+                               RNA_pointer_create(&ntree->id, &RNA_Node, node, &ptr);
+                               prop = RNA_struct_find_property(&ptr, "texture");
+
+                               buttons_texture_user_node_add(users, id, ntree, node,
+                                       category, RNA_struct_ui_icon(ptr.type), node->name);
+                       }
+                       else if(node->type == NODE_GROUP && node->id) {
+                               buttons_texture_users_find_nodetree(users, id, (bNodeTree*)node->id, category);
+                       }
+               }
+       }
+}
+
+static void buttons_texture_modifier_foreach(void *userData, Object *ob, ModifierData *md, const char *propname)
+{
+       PointerRNA ptr;
+       PropertyRNA *prop;
+       ListBase *users = userData;
+
+       RNA_pointer_create(&ob->id, &RNA_Modifier, md, &ptr);
+       prop = RNA_struct_find_property(&ptr, propname);
+
+       buttons_texture_user_property_add(users, &ob->id, ptr, prop,
+               "Modifiers", RNA_struct_ui_icon(ptr.type), md->name);
+}
+
+static void buttons_texture_users_from_context(ListBase *users, const bContext *C, SpaceButs *sbuts)
+{
+       Scene *scene= NULL;
+       Object *ob= NULL;
+       Material *ma= NULL;
+       Lamp *la= NULL;
+       World *wrld= NULL;
+       Brush *brush= NULL;
+       ID *pinid = sbuts->pinid;
+
+       /* get data from context */
+       if(pinid) {
+               if(GS(pinid->name) == ID_SCE)
+                       scene= (Scene*)pinid;
+               else if(GS(pinid->name) == ID_OB)
+                       ob= (Object*)pinid;
+               else if(GS(pinid->name) == ID_LA)
+                       la= (Lamp*)pinid;
+               else if(GS(pinid->name) == ID_WO)
+                       wrld= (World*)pinid;
+               else if(GS(pinid->name) == ID_MA)
+                       ma= (Material*)pinid;
+               else if(GS(pinid->name) == ID_BR)
+                       brush= (Brush*)pinid;
+       }
+
+       if(!scene)
+               scene= CTX_data_scene(C);
+       
+       if(!(pinid || pinid == &scene->id)) {
+               ob= (scene->basact)? scene->basact->object: NULL;
+               wrld= scene->world;
+               brush= paint_brush(paint_get_active(scene));
+       }
+
+       if(ob && ob->type == OB_LAMP && !la)
+               la= ob->data;
+       if(ob && !ma)
+               ma= give_current_material(ob, ob->actcol);
+
+       /* fill users */
+       users->first = users->last = NULL;
+
+       if(ma)
+               buttons_texture_users_find_nodetree(users, &ma->id, ma->nodetree, "Material");
+       if(la)
+               buttons_texture_users_find_nodetree(users, &la->id, la->nodetree, "Lamp");
+       if(wrld)
+               buttons_texture_users_find_nodetree(users, &wrld->id, wrld->nodetree, "World");
+
+       if(ob) {
+               ParticleSystem *psys= psys_get_current(ob);
+               MTex *mtex;
+               int a;
+
+               /* modifiers */
+               modifiers_foreachTexLink(ob, buttons_texture_modifier_foreach, users);
+
+               /* particle systems */
+               if(psys) {
+                       /* todo: these slots are not in the UI */
+                       for(a=0; a<MAX_MTEX; a++) {
+                               mtex = psys->part->mtex[a];
+
+                               if(mtex) {
+                                       PointerRNA ptr;
+                                       PropertyRNA *prop;
+
+                                       RNA_pointer_create(&psys->part->id, &RNA_ParticleSettingsTextureSlot, mtex, &ptr);
+                                       prop = RNA_struct_find_property(&ptr, "texture");
+
+                                       buttons_texture_user_property_add(users, &psys->part->id, ptr, prop,
+                                               "Particles", RNA_struct_ui_icon(&RNA_ParticleSettings), psys->name);
+                               }
+                       }
+               }
+
+               /* field */
+               if(ob->pd && ob->pd->forcefield == PFIELD_TEXTURE) {
+                       PointerRNA ptr;
+                       PropertyRNA *prop;
+
+                       RNA_pointer_create(&ob->id, &RNA_FieldSettings, ob->pd, &ptr);
+                       prop = RNA_struct_find_property(&ptr, "texture");
+
+                       buttons_texture_user_property_add(users, &ob->id, ptr, prop,
+                               "Fields", ICON_FORCE_TEXTURE, "Texture Field");
+               }
+       }
+
+       /* brush */
+       if(brush) {
+               PointerRNA ptr;
+               PropertyRNA *prop;
+
+               RNA_pointer_create(&brush->id, &RNA_BrushTextureSlot, &brush->mtex, &ptr);
+               prop= RNA_struct_find_property(&ptr, "texture");
+
+               buttons_texture_user_property_add(users, &brush->id, ptr, prop,
+                       "Brush", ICON_BRUSH_DATA, brush->id.name+2);
+       }
+}
+
+void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
+{
+       /* gatheravailable texture users in context. runs on every draw of
+          properties editor, before the buttons are created. */
+       ButsContextTexture *ct= sbuts->texuser;
+       Scene *scene= CTX_data_scene(C);
+
+       if(!scene_use_new_shading_nodes(scene)) {
+               if(ct) {
+                       MEM_freeN(ct);
+                       BLI_freelistN(&ct->users);
+                       sbuts->texuser= NULL;
+               }
+               
+               return;
+       }
+
+       if(!ct) {
+               ct= MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture");
+               sbuts->texuser= ct;
+       }
+       else {
+               BLI_freelistN(&ct->users);
+       }
+
+       buttons_texture_users_from_context(&ct->users, C, sbuts);
+
+       /* set one user as active based on active index */
+       if(ct->index >= BLI_countlist(&ct->users))
+               ct->index= 0;
+
+       ct->user = BLI_findlink(&ct->users, ct->index);
+       ct->texture = NULL;
+
+       if(ct->user) {
+               if(ct->user->ptr.data) {
+                       PointerRNA texptr;
+                       Tex *tex;
+
+                       /* get texture datablock pointer if it's a property */
+                       texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
+                       tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL;
+
+                       ct->texture = tex;
+               }
+               else if(ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) {
+                       ButsTextureUser *user;
+
+                       /* detect change of active texture node in same node tree, in that
+                          case we also automatically switch to the other node */
+                       for(user=ct->users.first; user; user=user->next) {
+                               if(user->ntree == ct->user->ntree && user->node != ct->user->node) {
+                                       if(user->node->flag & NODE_ACTIVE_TEXTURE) {
+                                               ct->user = user;
+                                               ct->index = BLI_findindex(&ct->users, user);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg))
+{
+       /* callback when selecting a texture user in the menu */
+       SpaceButs *sbuts = CTX_wm_space_buts(C);
+       ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
+       ButsTextureUser *user = (ButsTextureUser*)user_p;
+       PointerRNA texptr;
+       Tex *tex;
+
+       if(!ct)
+               return;
+
+       /* set user as active */
+       if(user->node) {
+               ED_node_set_active(CTX_data_main(C), user->ntree, user->node);
+               ct->texture = NULL;
+       }
+       else {
+               texptr = RNA_property_pointer_get(&user->ptr, user->prop);
+               tex = (RNA_struct_is_a(texptr.type, &RNA_Texture))? texptr.data: NULL;
+
+               ct->texture = tex;
+       }
+
+       ct->user = user;
+       ct->index = user->index;
+}
+
+static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg))
+{
+       /* callback when opening texture user selection menu, to create buttons. */
+       SpaceButs *sbuts = CTX_wm_space_buts(C);
+       ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
+       ButsTextureUser *user;
+       uiBlock *block = uiLayoutGetBlock(layout);
+       const char *last_category = NULL;
+
+       for(user=ct->users.first; user; user=user->next) {
+               uiBut *but;
+               char name[UI_MAX_NAME_STR];
+
+               /* add label per category */
+               if(!last_category || strcmp(last_category, user->category) != 0) {
+                       uiItemL(layout, user->category, ICON_NONE);
+                       but= block->buttons.last;
+                       but->flag= UI_TEXT_LEFT;
+               }
+
+               /* create button */
+               BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", user->name);
+
+               but = uiDefIconTextBut(block, BUT, 0, user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
+                       NULL, 0.0, 0.0, 0.0, 0.0, "");
+               uiButSetNFunc(but, template_texture_select, MEM_dupallocN(user), NULL);
+
+               last_category = user->category;
+       }
+}
+
+void uiTemplateTextureUser(uiLayout *layout, bContext *C)
+{
+       /* texture user selection dropdown menu. the available users have been
+          gathered before drawing in ButsContextTexture, we merely need to
+          display the current item. */
+       SpaceButs *sbuts = CTX_wm_space_buts(C);
+       ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
+       uiBlock *block = uiLayoutGetBlock(layout);
+       uiBut *but;
+       ButsTextureUser *user;
+       char name[UI_MAX_NAME_STR];
+
+       if(!ct)
+               return;
+
+       /* get current user */
+       user= ct->user;
+
+       if(!user) {
+               uiItemL(layout, "No textures in context.", ICON_NONE);
+               return;
+       }
+
+       /* create button */
+       BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name);
+
+       if(user->icon) {
+               but= uiDefIconTextMenuBut(block, template_texture_user_menu, NULL,
+                       user->icon, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
+       }
+       else {
+               but= uiDefMenuBut(block, template_texture_user_menu, NULL,
+                       name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, "");
+       }
+
+       /* some cosmetic tweaks */
+       but->type= MENU;
+       but->flag |= UI_TEXT_LEFT;
+       but->flag &= ~UI_ICON_SUBMENU;
+}
+
+/************************* Texture Show **************************/
+
+static void template_texture_show(bContext *C, void *data_p, void *prop_p)
+{
+       SpaceButs *sbuts = CTX_wm_space_buts(C);
+       ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
+       ButsTextureUser *user;
+
+       if(!ct)
+               return;
+
+       for(user=ct->users.first; user; user=user->next)
+               if(user->ptr.data == data_p && user->prop == prop_p)
+                       break;
+       
+       if(user) {
+               /* select texture */
+               template_texture_select(C, user, NULL);
+
+               /* change context */
+               sbuts->mainb= BCONTEXT_TEXTURE;
+               sbuts->mainbuser= sbuts->mainb;
+               sbuts->preview= 1;
+
+               /* redraw editor */
+               ED_area_tag_redraw(CTX_wm_area(C));
+       }
+}
+
+void uiTemplateTextureShow(uiLayout *layout, bContext *C, PointerRNA *ptr, PropertyRNA *prop)
+{
+       /* button to quickly show texture in texture tab */
+       SpaceButs *sbuts = CTX_wm_space_buts(C);
+       ButsContextTexture *ct= (sbuts)? sbuts->texuser: NULL;
+       ButsTextureUser *user;
+
+       /* only show button in other tabs in properties editor */
+       if(!ct || sbuts->mainb == BCONTEXT_TEXTURE)
+               return;
+
+       /* find corresponding texture user */
+       for(user=ct->users.first; user; user=user->next)
+               if(user->ptr.data == ptr->data && user->prop == prop)
+                       break;
+       
+       /* draw button */
+       if(user) {
+               uiBlock *block = uiLayoutGetBlock(layout);
+               uiBut *but;
+               
+               but= uiDefIconBut(block, BUT, 0, ICON_BUTS, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+                       NULL, 0.0, 0.0, 0.0, 0.0, "Show texture in texture tab");
+               uiButSetFunc(but, template_texture_show, user->ptr.data, user->prop);
+       }
+}
+
index 4c328d1..0c326af 100644 (file)
@@ -104,6 +104,12 @@ static void buttons_free(SpaceLink *sl)
 
        if(sbuts->path)
                MEM_freeN(sbuts->path);
+       
+       if(sbuts->texuser) {
+               ButsContextTexture *ct= sbuts->texuser;
+               BLI_freelistN(&ct->users);
+               MEM_freeN(ct);
+       }
 }
 
 /* spacetype; init callback */
@@ -127,6 +133,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
        /* clear or remove stuff from old */
        sbutsn->ri= NULL;
        sbutsn->path= NULL;
+       sbutsn->texuser= NULL;
        
        return (SpaceLink *)sbutsn;
 }
index 3b98763..c29553a 100644 (file)
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
 #include "BKE_mesh.h"
+#include "BKE_scene.h"
 #include "BKE_screen.h"
 
 #include "IMB_imbuf_types.h"
@@ -81,7 +84,7 @@ Image *ED_space_image(SpaceImage *sima)
 /* called to assign images to UV faces */
 void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
 {
-       ED_uvedit_assign_image(scene, obedit, ima, sima->image);
+       ED_uvedit_assign_image(CTX_data_main(C), scene, obedit, ima, sima->image);
        
        /* change the space ima after because uvedit_face_visible uses the space ima
         * to check if the face is displayed in UV-localview */
@@ -572,6 +575,7 @@ static void image_dropboxes(void)
 
 static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
 {
+       Scene *scene = CTX_data_scene(C);
        SpaceImage *sima= CTX_wm_space_image(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima;
@@ -586,19 +590,31 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
        else if(obedit && obedit->type == OB_MESH) {
                Mesh *me= (Mesh*)obedit->data;
                EditMesh *em= BKE_mesh_get_editmesh(me);
-               MTFace *tf;
-               
-               if(em && EM_texFaceCheck(em)) {
-                       sima->image= NULL;
-                       
-                       tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
+               int sloppy= 1; /* partially selected face is ok */
+
+               if(scene_use_new_shading_nodes(scene)) {
+                       /* new shading system, get image from material */
+                       EditFace *efa= EM_get_actFace(em, sloppy);
+
+                       if(efa)
+                               ED_object_get_active_image(obedit, efa->mat_nr, &sima->image, NULL, NULL);
+               }
+               else {
+                       /* old shading system, we set texface */
+                       MTFace *tf;
                        
-                       if(tf) {
-                               /* don't need to check for pin here, see above */
-                               sima->image= tf->tpage;
+                       if(em && EM_texFaceCheck(em)) {
+                               sima->image= NULL;
+                               
+                               tf = EM_get_active_mtface(em, NULL, NULL, sloppy);
                                
-                               if(sima->flag & SI_EDITTILE);
-                               else sima->curtile= tf->tile;
+                               if(tf) {
+                                       /* don't need to check for pin here, see above */
+                                       sima->image= tf->tpage;
+                                       
+                                       if(sima->flag & SI_EDITTILE);
+                                       else sima->curtile= tf->tile;
+                               }
                        }
                }
 
index 991b355..f33b784 100644 (file)
@@ -25,6 +25,7 @@ set(INC
        ../../blenlib
        ../../blenloader
        ../../imbuf
+       ../../gpu
        ../../makesdna
        ../../makesrna
        ../../nodes
index c4309dc..6b72fd0 100644 (file)
@@ -4,7 +4,7 @@ Import ('env')
 sources = env.Glob('*.c')
 
 incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
-incs += ' ../../nodes ../../render/extern/include ../../blenloader'
+incs += ' ../../nodes ../../render/extern/include ../../blenloader ../../gpu'
 incs += ' ../../windowmanager #intern/guardedalloc #extern/glew/include'
 defs = []
 cf = []
index a1b7056..23855ff 100644 (file)
@@ -90,6 +90,8 @@
 
 #include "RNA_enum_types.h"
 
+#include "GPU_material.h"
+
 #include "node_intern.h"
 
 static EnumPropertyItem socket_in_out_items[] = {
@@ -598,6 +600,8 @@ static int has_nodetree(bNodeTree *ntree, bNodeTree *lookup)
 
 void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
 {
+       int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE);
+
        nodeSetActive(ntree, node);
        
        if(node->type!=NODE_GROUP) {
@@ -621,6 +625,15 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
                                        ED_node_generic_update(bmain, ntree, node);
                        }
 
+                       /* if active texture changed, free glsl materials */
+                       if((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
+                               Material *ma;
+
+                               for(ma=bmain->mat.first; ma; ma=ma->id.next)
+                                       if(ma->nodetree && ma->use_nodes && has_nodetree(ma->nodetree, ntree))
+                                               GPU_material_free(ma);
+                       }
+
                        WM_main_add_notifier(NC_MATERIAL|ND_NODES, node->id);
                }
                else if(ntree->type==NTREE_COMPOSIT) {
index 806a6f9..5aa15cc 100644 (file)
@@ -215,6 +215,11 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t
                        }
                }
 
+               /* also preserve mapping for texture nodes */
+               if(node_from->typeinfo->nclass == NODE_CLASS_TEXTURE &&
+                  node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE)
+                       memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase));
+
                /* remove node */
                node_remove_linked(ntree, node_prev);
        }
@@ -503,6 +508,10 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo
        but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK;
        but->poin= (char*)but;
        but->func_argN = arg;
+
+       if(sock->link && sock->link->fromnode)
+               if(sock->link->fromnode->flag & NODE_ACTIVE_TEXTURE)
+                       but->flag |= UI_BUT_NODE_ACTIVE;
 }
 
 /**************************** Node Tree Layout *******************************/
index 670943a..e23824a 100644 (file)
 
 #include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
 #include "DNA_property_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_view3d_types.h"
-#include "DNA_object_types.h"
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_effect.h"
@@ -52,6 +53,7 @@
 #include "BKE_material.h"
 #include "BKE_paint.h"
 #include "BKE_property.h"
+#include "BKE_scene.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -64,6 +66,7 @@
 #include "GPU_material.h"
 
 #include "ED_mesh.h"
+#include "ED_uvedit.h"
 
 #include "view3d_intern.h"     // own include
 
@@ -619,7 +622,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
        ddm->release(ddm);
 }
 
-void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
+void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
 {
        Mesh *me= ob->data;
        
@@ -676,3 +679,179 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 }
 
+/************************** NEW SHADING NODES ********************************/
+
+typedef struct TexMatCallback {
+       Scene *scene;
+       Object *ob;
+       Mesh *me;
+       DerivedMesh *dm;
+} TexMatCallback;
+
+static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
+{
+       /* all we have to do here is simply enable the GLSL material, but note
+          that the GLSL code will give different result depending on the drawtype,
+          in texture draw mode it will output the active texture node, in material
+          draw mode it will show the full material. */
+       GPU_enable_material(mat_nr, attribs);
+}
+
+static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
+{
+       /* texture draw mode without GLSL */
+       TexMatCallback *data= (TexMatCallback*)userData;
+       GPUVertexAttribs *gattribs = attribs;
+       Image *ima;
+       ImageUser *iuser;
+       bNode *node;
+       int texture_set= 0;
+
+       /* draw image texture if we find one */
+       if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
+               /* get openl texture */
+               int mipmap= 1;
+               int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
+               float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+               if(bindcode) {
+                       NodeTexBase *texbase= node->storage;
+
+                       /* disable existing material */
+                       GPU_disable_material();
+                       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
+                       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
+                       glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+
+                       /* bind texture */
+                       glEnable(GL_COLOR_MATERIAL);
+                       glEnable(GL_TEXTURE_2D);
+
+                       glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+                       glColor3f(1.0f, 1.0f, 1.0f);
+
+                       glMatrixMode(GL_TEXTURE);
+                       glLoadMatrixf(texbase->tex_mapping.mat);
+                       glMatrixMode(GL_MODELVIEW);
+
+                       /* use active UV texture layer */
+                       memset(gattribs, 0, sizeof(*gattribs));
+
+                       gattribs->layer[0].type= CD_MTFACE;
+                       gattribs->layer[0].name[0]= '\0';
+                       gattribs->layer[0].gltexco= 1;
+                       gattribs->totlayer= 1;
+
+                       texture_set= 1;
+               }
+       }
+
+       if(!texture_set) {
+               glMatrixMode(GL_TEXTURE);
+               glLoadIdentity();
+               glMatrixMode(GL_MODELVIEW);
+
+               /* disable texture */
+               glDisable(GL_TEXTURE_2D);
+               glDisable(GL_COLOR_MATERIAL);
+
+               /* draw single color */
+               GPU_enable_material(mat_nr, attribs);
+       }
+}
+
+static int tex_mat_set_face_mesh_cb(void *userData, int index)
+{
+       /* faceselect mode face hiding */
+       TexMatCallback *data= (TexMatCallback*)userData;
+       Mesh *me = (Mesh*)data->me;
+       MFace *mface = &me->mface[index];
+
+       return !(mface->flag & ME_HIDE);
+}
+
+static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
+{
+       /* editmode face hiding */
+       EditFace *efa= EM_get_face_for_index(index);
+
+       return !(efa->h);
+}
+
+void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
+{
+       if(!scene_use_new_shading_nodes(scene)) {
+               draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, faceselect);
+               return;
+       }
+
+       /* set opengl state for negative scale & color */
+       if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
+       else glFrontFace(GL_CCW);
+
+       glEnable(GL_LIGHTING);
+
+       if(ob->mode & OB_MODE_WEIGHT_PAINT) {
+               /* weight paint mode exception */
+               int useColors= 1;
+
+               dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
+                       ob->data, useColors, GPU_enable_material, NULL);
+       }
+       else {
+               Mesh *me= ob->data;
+               TexMatCallback data = {scene, ob, me, dm};
+               int (*set_face_cb)(void*, int);
+               int glsl;
+               
+               /* face hiding callback depending on mode */
+               if(ob == scene->obedit)
+                       set_face_cb= tex_mat_set_face_editmesh_cb;
+               else if(faceselect)
+                       set_face_cb= tex_mat_set_face_mesh_cb;
+               else
+                       set_face_cb= NULL;
+
+               /* test if we can use glsl */
+               glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
+
+               GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
+
+               if(glsl) {
+                       /* draw glsl */
+                       dm->drawMappedFacesMat(dm,
+                               tex_mat_set_material_cb,
+                               set_face_cb, &data);
+               }
+               else {
+                       float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+                       /* draw textured */
+                       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
+                       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
+                       glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
+
+                       dm->drawMappedFacesMat(dm,
+                               tex_mat_set_texture_cb,
+                               set_face_cb, &data);
+               }
+
+               GPU_end_object_materials();
+       }
+
+       /* reset opengl state */
+       glDisable(GL_COLOR_MATERIAL);
+       glDisable(GL_TEXTURE_2D);
+       glDisable(GL_LIGHTING);
+       glBindTexture(GL_TEXTURE_2D, 0);
+       glFrontFace(GL_CCW);
+
+       glMatrixMode(GL_TEXTURE);
+       glLoadIdentity();
+       glMatrixMode(GL_MODELVIEW);
+
+       /* faceselect mode drawing over textured mesh */
+       if(!(ob == scene->obedit) && faceselect)
+               draw_mesh_face_select(rv3d, ob->data, dm);
+}
+
index f2bd4b5..8e592ad 100644 (file)
 
 /* this condition has been made more complex since editmode can draw textures */
 #define CHECK_OB_DRAWTEXTURE(vd, dt)                                          \
-       ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) ||                             \
+       ((ELEM(vd->drawtype, OB_TEXTURE, OB_MATERIAL) && dt>OB_SOLID) ||          \
        (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
 
 static void draw_bounding_volume(Scene *scene, Object *ob, char type);
@@ -252,6 +252,8 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
                return 0;
        if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
                return 0;
+       if(scene_use_new_shading_nodes(scene))
+               return 0;
        
        return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
 }
index 51bbf59..8e20f33 100644 (file)
@@ -2229,11 +2229,17 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
 {
        CustomDataMask mask= 0;
 
-       if((v3d->drawtype == OB_TEXTURE) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
+       if(ELEM(v3d->drawtype, OB_TEXTURE, OB_MATERIAL) || ((v3d->drawtype == OB_SOLID) && (v3d->flag2 & V3D_SOLID_TEX))) {
                mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
 
-               if(scene->gm.matmode == GAME_MAT_GLSL)
-                       mask |= CD_MASK_ORCO;
+               if(scene_use_new_shading_nodes(scene)) {
+                       if(v3d->drawtype == OB_MATERIAL)
+                               mask |= CD_MASK_ORCO;
+               }
+               else {
+                       if(scene->gm.matmode == GAME_MAT_GLSL)
+                               mask |= CD_MASK_ORCO;
+               }
        }
 
        return mask;
index 62b875c..173ab80 100644 (file)
@@ -37,7 +37,9 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_object_types.h"
+#include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_node_types.h"
 #include "DNA_scene_types.h"
 
 #include "BLI_math.h"
 #include "BKE_depsgraph.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
 #include "BKE_mesh.h"
+#include "BKE_node.h"
 #include "BKE_report.h"
+#include "BKE_scene.h"
 
 #include "ED_image.h"
 #include "ED_mesh.h"
+#include "ED_node.h"
 #include "ED_uvedit.h"
 #include "ED_object.h"
 #include "ED_screen.h"
@@ -87,9 +94,46 @@ int ED_uvedit_test(Object *obedit)
        return ret;
 }
 
+/**************************** object active image *****************************/
+
+static int is_image_texture_node(bNode *node)
+{
+       return ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_TEX_ENVIRONMENT);
+}
+
+int ED_object_get_active_image(Object *ob, int mat_nr, Image **ima, ImageUser **iuser, bNode **node_r)
+{
+       Material *ma= give_current_material(ob, mat_nr);
+       bNode *node= (ma && ma->use_nodes)? nodeGetActiveTexture(ma->nodetree): NULL;
+
+       if(node && is_image_texture_node(node)) {
+               if(ima) *ima= (Image*)node->id;
+               if(iuser) *iuser= NULL;
+               if(node_r) *node_r= node;
+               return TRUE;
+       }
+       
+       if(ima) *ima= NULL;
+       if(iuser) *iuser= NULL;
+       if(node_r) *node_r= node;
+
+       return FALSE;
+}
+
+void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *ima)
+{
+       Material *ma= give_current_material(ob, mat_nr);
+       bNode *node= (ma && ma->use_nodes)? nodeGetActiveTexture(ma->nodetree): NULL;
+
+       if(node && is_image_texture_node(node)) {
+               node->id= &ima->id;
+               ED_node_generic_update(bmain, ma->nodetree, node);
+       }
+}
+
 /************************* assign image ************************/
 
-void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *previma)
+void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma)
 {
        EditMesh *em;
        EditFace *efa;
@@ -109,35 +153,46 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
                BKE_mesh_end_editmesh(obedit->data, em);
                return;
        }
-       
-       /* ensure we have a uv layer */
-       if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) {
-               EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL);
-               update= 1;
+
+       if(scene_use_new_shading_nodes(scene)) {
+               /* new shading system, assign image in material */
+               int sloppy= 1;
+               EditFace *efa= EM_get_actFace(em, sloppy);
+
+               if(efa)
+                       ED_object_assign_active_image(bmain, obedit, efa->mat_nr, ima);
        }
+       else {
+               /* old shading system, assign image to selected faces */
+               
+               /* ensure we have a uv layer */
+               if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) {
+                       EM_add_data_layer(em, &em->fdata, CD_MTFACE, NULL);
+                       update= 1;
+               }
 
-       /* now assign to all visible faces */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               /* now assign to all visible faces */
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-               if(uvedit_face_visible(scene, previma, efa, tf)) {
-                       if(ima) {
-                               tf->tpage= ima;
-                               
-                               if(ima->id.us==0) id_us_plus(&ima->id);
-                               else id_lib_extern(&ima->id);
-                       }
-                       else {
-                               tf->tpage= NULL;
-                       }
+                       if(uvedit_face_visible(scene, previma, efa, tf)) {
+                               if(ima) {
+                                       tf->tpage= ima;
+                                       
+                                       if(ima->id.us==0) id_us_plus(&ima->id);
+                                       else id_lib_extern(&ima->id);
+                               }
+                               else
+                                       tf->tpage= NULL;
 
-                       update = 1;
+                               update = 1;
+                       }
                }
-       }
 
-       /* and update depdency graph */
-       if(update)
-               DAG_id_tag_update(obedit->data, 0);
+               /* and update depdency graph */
+               if(update)
+                       DAG_id_tag_update(obedit->data, 0);
+       }
 
        BKE_mesh_end_editmesh(obedit->data, em);
 }
index 29a9ae8..11cd50a 100644 (file)
@@ -51,6 +51,7 @@
 #include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
 #include "BKE_image.h"
+#include "BKE_main.h"
 #include "BKE_mesh.h"
 
 #include "PIL_time.h"
@@ -73,6 +74,7 @@
 
 static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
 {
+       Main *bmain= CTX_data_main(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        MTFace *tf;
@@ -118,7 +120,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
        }
        
        if(ima)
-               ED_uvedit_assign_image(scene, obedit, ima, NULL);
+               ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
        
        /* select new UV's */
        for(efa=em->faces.first; efa; efa=efa->next) {
index 4c82826..d08d7cf 100644 (file)
@@ -62,7 +62,7 @@
 #include "BKE_material.h"
 #include "BKE_node.h"
 #include "BKE_object.h"
-
+#include "BKE_scene.h"
 
 #include "BLI_threads.h"
 #include "BLI_blenlib.h"
@@ -952,15 +952,17 @@ static struct GPUMaterialState {
 } GMS = {NULL};
 
 /* fixed function material, alpha handed by caller */
-static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob)
+static void gpu_material_to_fixed(GPUMaterialFixed *smat, const Material *bmat, const int gamma, const Object *ob, const int new_shading_nodes)
 {
-       if (bmat->mode & MA_SHLESS) {
+       if(new_shading_nodes || bmat->mode & MA_SHLESS) {
                copy_v3_v3(smat->diff, &bmat->r);
                smat->diff[3]= 1.0;
 
-               if(gamma) {
+               if(gamma)
                        linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
-               }       
+
+               zero_v4(smat->spec);
+               smat->hard= 0;
        }
        else {
                mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit);
@@ -1001,6 +1003,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
        GPUBlendMode alphablend;
        int a;
        int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
+       int new_shading_nodes = scene_use_new_shading_nodes(scene);
        
        /* initialize state */
        memset(&GMS, 0, sizeof(GMS));
@@ -1032,7 +1035,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
 
        /* no materials assigned? */
        if(ob->totcol==0) {
-               gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob);
+               gpu_material_to_fixed(&GMS.matbuf[0], &defmaterial, 0, ob, new_shading_nodes);
 
                /* do material 1 too, for displists! */
                memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed));
@@ -1049,7 +1052,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
        for(a=1; a<=ob->totcol; a++) {
                /* find a suitable material */
                ma= give_current_material(ob, a);
-               if(!glsl) ma= gpu_active_node_material(ma);
+               if(!glsl && !new_shading_nodes) ma= gpu_active_node_material(ma);
                if(ma==NULL) ma= &defmaterial;
 
                /* create glsl material if requested */
@@ -1062,7 +1065,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
                }
                else {
                        /* fixed function opengl materials */
-                       gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob);
+                       gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob, new_shading_nodes);
 
                        alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
                        if(do_alpha_pass && GMS.alphapass)
@@ -1223,6 +1226,7 @@ void GPU_end_object_materials(void)
 
 int GPU_default_lights(void)
 {
+       float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}, position[4];
        int a, count = 0;
        
        /* initialize */
@@ -1248,27 +1252,28 @@ int GPU_default_lights(void)
 
        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
 
-       glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec); 
-       glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col); 
-       glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec); 
-
-       glLightfv(GL_LIGHT1, GL_POSITION, U.light[1].vec); 
-       glLightfv(GL_LIGHT1, GL_DIFFUSE, U.light[1].col); 
-       glLightfv(GL_LIGHT1, GL_SPECULAR, U.light[1].spec); 
-
-       glLightfv(GL_LIGHT2, GL_POSITION, U.light[2].vec); 
-       glLightfv(GL_LIGHT2, GL_DIFFUSE, U.light[2].col); 
-       glLightfv(GL_LIGHT2, GL_SPECULAR, U.light[2].spec); 
-
        for(a=0; a<8; a++) {
                if(a<3) {
                        if(U.light[a].flag) {
                                glEnable(GL_LIGHT0+a);
+
+                               normalize_v3_v3(position, U.light[a].vec);
+                               position[3]= 0.0f;
+                               
+                               glLightfv(GL_LIGHT0+a, GL_POSITION, position); 
+                               glLightfv(GL_LIGHT0+a, GL_DIFFUSE, U.light[a].col); 
+                               glLightfv(GL_LIGHT0+a, GL_SPECULAR, U.light[a].spec); 
+
                                count++;
                        }
-                       else
+                       else {
                                glDisable(GL_LIGHT0+a);
-                       
+
+                               glLightfv(GL_LIGHT0+a, GL_POSITION, zero); 
+                               glLightfv(GL_LIGHT0+a, GL_DIFFUSE, zero); 
+                               glLightfv(GL_LIGHT0+a, GL_SPECULAR, zero);
+                       }
+
                        // clear stuff from other opengl lamp usage
                        glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0);
                        glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0);
index 9344b4e..02ba2eb 100644 (file)
@@ -1415,29 +1415,33 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
                if(((GPUMaterial*)link->data)->scene == scene)
                        return link->data;
 
+       /* allocate material */
        mat = GPU_material_construct_begin(ma);
        mat->scene = scene;
 
        if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
+               /* create nodes */
                ntreeGPUMaterialNodes(ma->nodetree, mat);
        }
        else {
+               /* create material */
                outlink = GPU_blender_material(mat, ma);
                GPU_material_output_link(mat, outlink);
        }
 
-       if(gpu_do_color_management(mat))
-               if(mat->outlink)
-                       GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
+       if(!scene_use_new_shading_nodes(scene)) {
+               if(gpu_do_color_management(mat))
+                       if(mat->outlink)
+                               GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
+       }
 
-       /*if(!GPU_material_construct_end(mat)) {
-               GPU_material_free(mat);
-               mat= NULL;
-               return 0;
-       }*/
 
        GPU_material_construct_end(mat);
 
+       /* note that even if building the shader fails in some way, we still keep
+          it to avoid trying to compile again and again, and simple do not use
+          the actual shader on drawing */
+
        link = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
        link->data = mat;
        BLI_addtail(&ma->gpumaterial, link);
index 289c7ac..3e74243 100644 (file)
@@ -145,6 +145,8 @@ typedef struct SpaceButs {
        void *path;                                             /* runtime */
        int pathflag, dataicon;                 /* runtime */
        ID *pinid;
+
+       void *texuser;
 } SpaceButs;
 
 typedef struct SpaceSeq {
index bb07fa8..d698e7c 100644 (file)
@@ -102,7 +102,8 @@ EnumPropertyItem viewport_shade_items[] = {
        {OB_BOUNDBOX, "BOUNDBOX", ICON_BBOX, "Bounding Box", "Display the object's local bounding boxes only"},
        {OB_WIRE, "WIREFRAME", ICON_WIRE, "Wireframe", "Display the object as wire edges"},
        {OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid, lit with default OpenGL lights"},
-       {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Textured", "Display the object solid, with face-assigned textures"},
+       {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Texture", "Display the object solid, with a texture"},
+       {OB_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, "Material", "Display objects solid, with GLSL material"},
        {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"},
        {0, NULL, 0, NULL, NULL}};
 
@@ -114,13 +115,14 @@ EnumPropertyItem viewport_shade_items[] = {
 
 #include "BLI_math.h"
 
-#include "BKE_screen.h"
 #include "BKE_animsys.h"
 #include "BKE_brush.h"
 #include "BKE_colortools.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_paint.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
 
 #include "ED_image.h"
 #include "ED_node.h"
@@ -461,10 +463,12 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C
        RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_WIRE);
        RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID);
        RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE);
+
+       if(scene_use_new_shading_nodes(scene))
+               RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_MATERIAL);
        
-       if(type->view_draw) {
+       if(type->view_draw)
                RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER);
-       }
 
        RNA_enum_item_end(&item, &totitem);
        *free= 1;
index 9ff56f1..366ba1d 100644 (file)
@@ -465,6 +465,9 @@ void RNA_api_ui_layout(StructRNA *srna)
        parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "");
        RNA_def_property_flag(parm, PROP_REQUIRED);
 
+       func= RNA_def_function(srna, "template_texture_user", "uiTemplateTextureUser");
+       RNA_def_function_flag(func, FUNC_USE_CONTEXT);
+
        func= RNA_def_function(srna, "template_keymap_item_properties", "uiTemplateKeymapItemProperties");
        parm= RNA_def_pointer(func, "item", "KeyMapItem", "", "");
        RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);
index ebcef97..dcfdb97 100644 (file)
@@ -242,6 +242,29 @@ static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNode
                node_data_from_gpu_stack(ns[i], &gs[i]);
 }
 
+bNode *nodeGetActiveTexture(bNodeTree *ntree)
+{
+       /* this is the node we texture paint and draw in textured draw */
+       bNode *node;
+
+       if(!ntree)
+               return NULL;
+
+       /* check for group edit */
+       for(node= ntree->nodes.first; node; node= node->next)
+               if(node->flag & NODE_GROUP_EDIT)
+                       break;
+
+       if(node)
+               ntree= (bNodeTree*)node->id;
+
+       for(node= ntree->nodes.first; node; node= node->next)
+               if(node->flag & NODE_ACTIVE_TEXTURE)
+                       return node;
+       
+       return NULL;
+}
+
 void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs)
 {
        bNodeExec *nodeexec;
index 2f29792..bf31f82 100644 (file)
@@ -374,6 +374,8 @@ void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *p
 void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){}
 void uiTemplateNodeLink(struct uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {}
 void uiTemplateNodeView(struct uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {}
+void uiTemplateTextureUser(struct uiLayout *layout, struct bContext *C) {}
+void uiTemplateTextureShow(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop) {}
 void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){}
 void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){}
 void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){}