svn merge -r41650:41655 ^/trunk/blender --- cycles merge, this wont copile, still need to manually update some funcs

This commit is contained in:
Campbell Barton 2011-11-10 03:05:11 +00:00
commit 685041d53a
34 changed files with 1562 additions and 203 deletions

@ -379,6 +379,14 @@ struct DerivedMesh {
float t), float t),
void *userData); 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 /* Release reference to the DerivedMesh. This function decides internally
* if the DerivedMesh will be freed, or cached for later use. */ * if the DerivedMesh will be freed, or cached for later use. */
void (*release)(DerivedMesh *dm); void (*release)(DerivedMesh *dm);

@ -351,6 +351,7 @@ struct bNode *nodeGetActive(struct bNodeTree *ntree);
struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype); struct bNode *nodeGetActiveID(struct bNodeTree *ntree, short idtype);
int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id); int nodeSetActiveID(struct bNodeTree *ntree, short idtype, struct ID *id);
void nodeClearActiveID(struct bNodeTree *ntree, short idtype); void nodeClearActiveID(struct bNodeTree *ntree, short idtype);
struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree);
void nodeUpdate(struct bNodeTree *ntree, struct bNode *node); void nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
int nodeUpdateID(struct bNodeTree *ntree, struct ID *id); int nodeUpdateID(struct bNodeTree *ntree, struct ID *id);

@ -1388,6 +1388,85 @@ static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); 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) static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
{ {
CDDerivedMesh *cddm = (CDDerivedMesh*) dm; CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
@ -1606,6 +1685,7 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->drawMappedFaces = cdDM_drawMappedFaces; dm->drawMappedFaces = cdDM_drawMappedFaces;
dm->drawMappedFacesTex = cdDM_drawMappedFacesTex; dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL; dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
dm->foreachMappedVert = cdDM_foreachMappedVert; dm->foreachMappedVert = cdDM_foreachMappedVert;
dm->foreachMappedEdge = cdDM_foreachMappedEdge; dm->foreachMappedEdge = cdDM_foreachMappedEdge;

@ -1120,6 +1120,141 @@ static void bmDM_drawFacesGLSL(DerivedMesh *dm,
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
} }
static void bmDM_drawMappedFacesMat(DerivedMesh *dm,
void (*setMaterial)(void *userData, int, void *attribs),
int (*setFace)(void *userData, int index), void *userData)
{
EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
EditMesh *em= bmdm->em;
float (*vertexCos)[3]= bmdm->vertexCos;
float (*vertexNos)[3]= bmdm->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(bmdm->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 bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
{ {
EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm; EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
@ -1561,6 +1696,7 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *UNUSED(ob),
bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces; bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex; bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL; bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
bmdm->dm.drawMappedFacesMat = bmDM_drawMappedFacesMat;
bmdm->dm.drawFacesTex = bmDM_drawFacesTex; bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL; bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
bmdm->dm.drawUVEdges = bmDM_drawUVEdges; bmdm->dm.drawUVEdges = bmDM_drawUVEdges;

@ -1314,11 +1314,15 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
if(GS(node->id->name) == GS(tnode->id->name)) if(GS(node->id->name) == GS(tnode->id->name))
tnode->flag &= ~NODE_ACTIVE_ID; tnode->flag &= ~NODE_ACTIVE_ID;
} }
if(node->typeinfo->nclass == NODE_CLASS_TEXTURE)
tnode->flag &= ~NODE_ACTIVE_TEXTURE;
} }
node->flag |= NODE_ACTIVE; node->flag |= NODE_ACTIVE;
if(node->id) if(node->id)
node->flag |= NODE_ACTIVE_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 /* use flags are not persistent yet, groups might need different tagging, so we do it each time

@ -1750,6 +1750,155 @@ static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL); dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
} }
/* Only used by non-editmesh types */
static void cgdm_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 cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) { static void cgdm_drawFacesColored(DerivedMesh *dm, int UNUSED(useTwoSided), unsigned char *col1, unsigned char *col2) {
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = cgdm->ss; CCGSubSurf *ss = cgdm->ss;
@ -2711,6 +2860,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex; ccgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL; ccgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
ccgdm->dm.drawMappedFacesMat = cgdm_drawMappedFacesMat;
ccgdm->dm.drawUVEdges = cgdm_drawUVEdges; ccgdm->dm.drawUVEdges = cgdm_drawUVEdges;
ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp; ccgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;

@ -33,10 +33,14 @@
struct ARegionType; struct ARegionType;
struct EditFace; struct EditFace;
struct Image; struct Image;
struct Main;
struct ImageUser;
struct MTFace; struct MTFace;
struct Object; struct Object;
struct Scene; struct Scene;
struct SpaceImage;
struct bContext; struct bContext;
struct bNode;
struct wmKeyConfig; struct wmKeyConfig;
struct BMEditMesh; struct BMEditMesh;
struct BMLoop; struct BMLoop;
@ -47,9 +51,12 @@ struct MTexPoly;
void ED_operatortypes_uvedit(void); void ED_operatortypes_uvedit(void);
void ED_keymap_uvedit(struct wmKeyConfig *keyconf); 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_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_silent(struct Object *obedit);
int ED_uvedit_test(struct Object *obedit); int ED_uvedit_test(struct Object *obedit);

@ -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 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 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 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 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); void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname);

@ -332,7 +332,7 @@ static const char *template_id_browse_tip(StructRNA *type)
return N_("Browse ID data to be linked"); 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; uiBut *but;
uiBlock *block; uiBlock *block;
@ -479,6 +479,9 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
uiButSetFlag(but, UI_BUT_DISABLED); uiButSetFlag(but, UI_BUT_DISABLED);
} }
if(idcode == ID_TE)
uiTemplateTextureShow(layout, C, &template->ptr, template->prop);
uiBlockEndAlign(block); uiBlockEndAlign(block);
} }
@ -487,6 +490,7 @@ static void ui_template_id(uiLayout *layout, bContext *C, PointerRNA *ptr, const
TemplateID *template; TemplateID *template;
PropertyRNA *prop; PropertyRNA *prop;
StructRNA *type; StructRNA *type;
short idcode;
prop= RNA_struct_find_property(ptr, propname); 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; flag |= UI_ID_OPEN;
type= RNA_property_pointer_type(ptr, prop); 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 /* create UI elements for this template
* - template_ID makes a copy of the template data and assigns it to the relevant buttons * - template_ID makes a copy of the template data and assigns it to the relevant buttons
*/ */
if(template->idlb) { if(template->idlb) {
uiLayoutRow(layout, 1); 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); MEM_freeN(template);

@ -52,6 +52,7 @@
#include "BKE_displist.h" #include "BKE_displist.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_library.h" #include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h" #include "BKE_material.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_report.h" #include "BKE_report.h"
@ -379,6 +380,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
{ {
Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C); View3D *v3d= CTX_wm_view3d(C);
Base *base= ED_view3d_give_base_under_cursor(C, event->mval); Base *base= ED_view3d_give_base_under_cursor(C, event->mval);
@ -428,7 +430,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
ED_uvedit_assign_image(scene, obedit, ima, NULL); ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
if(exitmode) { if(exitmode) {
EDBM_LoadEditBMesh(scene, obedit); EDBM_LoadEditBMesh(scene, obedit);

@ -79,6 +79,7 @@
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_paint.h" #include "BKE_paint.h"
#include "BKE_report.h" #include "BKE_report.h"
#include "BKE_scene.h"
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BIF_glutil.h" #include "BIF_glutil.h"
@ -88,6 +89,7 @@
#include "ED_image.h" #include "ED_image.h"
#include "ED_screen.h" #include "ED_screen.h"
#include "ED_sculpt.h" #include "ED_sculpt.h"
#include "ED_uvedit.h"
#include "ED_view3d.h" #include "ED_view3d.h"
#include "WM_api.h" #include "WM_api.h"
@ -498,6 +500,40 @@ static void image_undo_free(ListBase *lb)
MEM_freeN(tile->rect); 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 */ /* fast projection bucket array lookup, use the safe version for bound checking */
static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2]) 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 side;
int face_index; int face_index;
MTFace *tf; MTFace *tf;
Image *ima;
ImBuf *ibuf; ImBuf *ibuf;
int xi, yi; int xi, yi;
@ -688,7 +725,8 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float
interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w); 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 (!ibuf) return 0;
if (interp) { 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 */ /* 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) { 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 */ /* This IS an adjacent face!, now lets check if the UVs are ok */
tf = ps->dm_mtface + face_index; 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; *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
/* first test if they have the same image */ /* 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_i1_fidx], tf->uv[i1_fidx]) &&
cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_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) { if (ps->do_layer_stencil) {
/* another UV layers image is masking this one's */ /* another UV layers image is masking this one's */
ImBuf *ibuf_other; ImBuf *ibuf_other;
Image *other_tpage = project_paint_face_image(ps, face_index);
const MTFace *tf_other = ps->dm_mtface_stencil + 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 */ /* BKE_image_get_ibuf - TODO - this may be slow */
unsigned char rgba_ub[4]; unsigned char rgba_ub[4];
float rgba_f[4]; float rgba_f[4];
@ -1464,9 +1506,10 @@ static ProjPixel *project_paint_uvpixel_init(
if (ps->tool==PAINT_TOOL_CLONE) { if (ps->tool==PAINT_TOOL_CLONE) {
if (ps->dm_mtface_clone) { if (ps->dm_mtface_clone) {
ImBuf *ibuf_other; ImBuf *ibuf_other;
Image *other_tpage = project_paint_face_image(ps, face_index);
const MTFace *tf_other = ps->dm_mtface_clone + 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 */ /* BKE_image_get_ibuf - TODO - this may be slow */
if (ibuf->rect_float) { if (ibuf->rect_float) {
@ -2684,11 +2727,8 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
LinkNode *node; LinkNode *node;
int face_index, image_index=0; int face_index, image_index=0;
ImBuf *ibuf = NULL; ImBuf *ibuf = NULL;
Image *tpage_last = NULL, *tpage;
Image *ima = NULL; Image *ima = NULL;
MTFace *tf;
Image *tpage_last = NULL;
if (ps->image_tot==1) { if (ps->image_tot==1) {
/* Simple loop, no context switching */ /* 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); face_index = GET_INT_FROM_POINTER(node->link);
/* Image context switching */ /* Image context switching */
tf = ps->dm_mtface+face_index; tpage = project_paint_face_image(ps, face_index);
if (tpage_last != tf->tpage) { if (tpage_last != tpage) {
tpage_last = tf->tpage; tpage_last = tpage;
for (image_index=0; image_index < ps->image_tot; image_index++) { for (image_index=0; image_index < ps->image_tot; image_index++) {
if (ps->projImages[image_index].ima == tpage_last) { if (ps->projImages[image_index].ima == tpage_last) {
@ -2876,7 +2916,7 @@ static void project_paint_begin(ProjPaintState *ps)
LinkNode *node; LinkNode *node;
ProjPaintImage *projIma; ProjPaintImage *projIma;
Image *tpage_last = NULL; Image *tpage_last = NULL, *tpage;
/* Face vars */ /* Face vars */
MFace *mf; MFace *mf;
@ -3213,7 +3253,9 @@ static void project_paint_begin(ProjPaintState *ps)
} }
#endif #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; float *v1coSS, *v2coSS, *v3coSS, *v4coSS=NULL;
@ -3286,17 +3328,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 */ if (image_index==-1 && BKE_image_get_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
BLI_linklist_append(&image_LinkList, tf->tpage); BLI_linklist_append(&image_LinkList, tpage);
image_index = ps->image_tot; image_index = ps->image_tot;
ps->image_tot++; ps->image_tot++;
} }
tpage_last = tf->tpage; tpage_last = tpage;
} }
if (image_index != -1) { if (image_index != -1) {
@ -4485,7 +4527,7 @@ static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPaint
) { ) {
ImBuf *ibuf; 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); ibuf= BKE_image_get_ibuf(newimage, s->sima? &s->sima->iuser: NULL);
if(ibuf && ibuf->rect) if(ibuf && ibuf->rect)

@ -38,6 +38,7 @@ set(SRC
buttons_context.c buttons_context.c
buttons_header.c buttons_header.c
buttons_ops.c buttons_ops.c
buttons_texture.c
space_buttons.c space_buttons.c
buttons_intern.h buttons_intern.h

@ -54,7 +54,6 @@
#include "BKE_screen.h" #include "BKE_screen.h"
#include "BKE_texture.h" #include "BKE_texture.h"
#include "RNA_access.h" #include "RNA_access.h"
#include "ED_armature.h" #include "ED_armature.h"
@ -66,13 +65,6 @@
#include "buttons_intern.h" // own include #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) static int set_pointer_type(ButsContextPath *path, bContextDataResult *result, StructRNA *type)
{ {
PointerRNA *ptr; PointerRNA *ptr;
@ -373,102 +365,141 @@ static int buttons_context_path_brush(ButsContextPath *path)
return 0; return 0;
} }
static int buttons_context_path_texture(ButsContextPath *path) static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct)
{ {
Material *ma; if(ct) {
Lamp *la; /* new shading system */
Brush *br; PointerRNA *ptr= &path->ptr[path->len-1];
World *wo; ID *id;
ParticleSystem *psys;
Tex *tex; /* if we already have a (pinned) texture, we're done */
PointerRNA *ptr= &path->ptr[path->len-1]; if(RNA_struct_is_a(ptr->type, &RNA_Texture))
int orig_len = path->len; return 1;
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++;
}
/* if we already have a (pinned) texture, we're done */
if(RNA_struct_is_a(ptr->type, &RNA_Texture)) {
return 1; return 1;
} }
/* try brush */ else {
if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) { /* old shading system */
br= path->ptr[path->len-1].data; 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(br) { /* if we already have a (pinned) texture, we're done */
tex= give_current_brush_texture(br); if(RNA_struct_is_a(ptr->type, &RNA_Texture)) {
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++;
return 1; return 1;
} }
} /* try brush */
/* try world */ if((path->tex_ctx == SB_TEXC_BRUSH) && buttons_context_path_brush(path)) {
if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) { br= path->ptr[path->len-1].data;
wo= path->ptr[path->len-1].data;
if(wo && GS(wo->id.name)==ID_WO) { if(br) {
tex= give_current_world_texture(wo); tex= give_current_brush_texture(br);
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++;
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;
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;
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]); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++; path->len++;
return 1; return 1;
} }
} }
} /* try world */
/* try material */ if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
if(buttons_context_path_material(path, 1)) { wo= path->ptr[path->len-1].data;
ma= path->ptr[path->len-1].data;
if(ma) { if(wo && GS(wo->id.name)==ID_WO) {
tex= give_current_material_texture(ma); tex= give_current_world_texture(wo);
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++; path->len++;
return 1; return 1;
}
} }
} /* try particles */
/* try lamp */ if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
if(buttons_context_path_data(path, OB_LAMP)) { if(path->ptr[path->len-1].type == &RNA_ParticleSettings) {
la= path->ptr[path->len-1].data; ParticleSettings *part = path->ptr[path->len-1].data;
if(la) { tex= give_current_particle_texture(part);
tex= give_current_lamp_texture(la); 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]); if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
path->len++; tex= give_current_particle_texture(psys->part);
return 1;
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++;
return 1;
}
}
} }
} /* try material */
/* try brushes again in case of no material, lamp, etc */ if(buttons_context_path_material(path, 1)) {
path->len = orig_len; ma= path->ptr[path->len-1].data;
if(buttons_context_path_brush(path)) {
br= path->ptr[path->len-1].data;
if(br) { if(ma) {
tex= give_current_brush_texture(br); tex= give_current_material_texture(ma);
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]); RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
path->len++; path->len++;
return 1; return 1;
}
}
/* 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;
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); found= buttons_context_path_material(path, 0);
break; break;
case BCONTEXT_TEXTURE: case BCONTEXT_TEXTURE:
found= buttons_context_path_texture(path); found= buttons_context_path_texture(path, sbuts->texuser);
break; break;
case BCONTEXT_BONE: case BCONTEXT_BONE:
found= buttons_context_path_bone(path); found= buttons_context_path_bone(path);
@ -580,6 +611,8 @@ void buttons_context_compute(const bContext *C, SpaceButs *sbuts)
PointerRNA *ptr; PointerRNA *ptr;
int a, pflag= 0, flag= 0; int a, pflag= 0, flag= 0;
buttons_texture_context_compute(C, sbuts);
if(!sbuts->path) if(!sbuts->path)
sbuts->path= MEM_callocN(sizeof(ButsContextPath), "ButsContextPath"); 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[] = { const char *buttons_context_dir[] = {
"world", "object", "mesh", "armature", "lattice", "curve", "world", "object", "mesh", "armature", "lattice", "curve",
"meta_ball", "lamp", "speaker", "camera", "material", "material_slot", "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}; "cloth", "soft_body", "fluid", "smoke", "collision", "brush", NULL};
int buttons_context(const bContext *C, const char *member, bContextDataResult *result) 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; return 1;
} }
else if(CTX_data_equals(member, "texture")) { 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; return 1;
} }
else if(CTX_data_equals(member, "material_slot")) { 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; return 1;
} }
else if(CTX_data_equals(member, "texture_node")) { else if(CTX_data_equals(member, "texture_user")) {
PointerRNA *ptr; ButsContextTexture *ct= sbuts->texuser;
if((ptr=get_pointer_type(path, &RNA_Material))) { if(!ct)
Material *ma= ptr->data; return 0; /* old shading system */
if(ma) { if(ct->user && ct->user->ptr.data) {
bNode *node= give_current_material_texture_node(ma); ButsTextureUser *user= ct->user;
CTX_data_pointer_set(result, &ma->id, &RNA_Node, node); CTX_data_pointer_set(result, user->ptr.id.data, user->ptr.type, user->ptr.data);
}
} }
return 1; 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")) { else if(CTX_data_equals(member, "texture_slot")) {
ButsContextTexture *ct= sbuts->texuser;
PointerRNA *ptr; PointerRNA *ptr;
if(ct)
return 0; /* new shading system */
if((ptr=get_pointer_type(path, &RNA_Material))) { if((ptr=get_pointer_type(path, &RNA_Material))) {
Material *ma= ptr->data; Material *ma= ptr->data;

@ -31,14 +31,20 @@
#ifndef ED_BUTTONS_INTERN_H #ifndef ED_BUTTONS_INTERN_H
#define ED_BUTTONS_INTERN_H #define ED_BUTTONS_INTERN_H
#include "DNA_listBase.h"
#include "RNA_types.h"
struct ARegion; struct ARegion;
struct ARegionType; struct ARegionType;
struct ID;
struct SpaceButs;
struct Tex;
struct bContext; struct bContext;
struct bContextDataResult; struct bContextDataResult;
struct SpaceButs; struct bNode;
struct bNodeTree;
struct uiLayout; struct uiLayout;
struct wmOperatorType; struct wmOperatorType;
struct ID;
/* buts->scaflag */ /* buts->scaflag */
#define BUTS_SENS_SEL 1 #define BUTS_SENS_SEL 1
@ -53,6 +59,42 @@ struct ID;
#define BUTS_SENS_STATE 512 #define BUTS_SENS_STATE 512
#define BUTS_ACT_STATE 1024 #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 */ /* internal exports only */
/* buttons_header.c */ /* 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 */ 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 */ /* buttons_ops.c */
void BUTTONS_OT_file_browse(struct wmOperatorType *ot); void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
void BUTTONS_OT_directory_browse(struct wmOperatorType *ot); void BUTTONS_OT_directory_browse(struct wmOperatorType *ot);

@ -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);
}
}

@ -104,6 +104,12 @@ static void buttons_free(SpaceLink *sl)
if(sbuts->path) if(sbuts->path)
MEM_freeN(sbuts->path); MEM_freeN(sbuts->path);
if(sbuts->texuser) {
ButsContextTexture *ct= sbuts->texuser;
BLI_freelistN(&ct->users);
MEM_freeN(ct);
}
} }
/* spacetype; init callback */ /* spacetype; init callback */
@ -127,6 +133,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
/* clear or remove stuff from old */ /* clear or remove stuff from old */
sbutsn->ri= NULL; sbutsn->ri= NULL;
sbutsn->path= NULL; sbutsn->path= NULL;
sbutsn->texuser= NULL;
return (SpaceLink *)sbutsn; return (SpaceLink *)sbutsn;
} }

@ -47,7 +47,10 @@
#include "BKE_colortools.h" #include "BKE_colortools.h"
#include "BKE_context.h" #include "BKE_context.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_scene.h"
#include "BKE_screen.h" #include "BKE_screen.h"
#include "IMB_imbuf_types.h" #include "IMB_imbuf_types.h"
@ -81,7 +84,7 @@ Image *ED_space_image(SpaceImage *sima)
/* called to assign images to UV faces */ /* called to assign images to UV faces */
void ED_space_image_set(bContext *C, SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) 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 /* change the space ima after because uvedit_face_visible uses the space ima
* to check if the face is displayed in UV-localview */ * to check if the face is displayed in UV-localview */
@ -570,6 +573,7 @@ static void image_dropboxes(void)
static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
{ {
Scene *scene = CTX_data_scene(C);
SpaceImage *sima= CTX_wm_space_image(C); SpaceImage *sima= CTX_wm_space_image(C);
Object *obedit= CTX_data_edit_object(C); Object *obedit= CTX_data_edit_object(C);
Image *ima; Image *ima;
@ -584,19 +588,31 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa))
else if(obedit && obedit->type == OB_MESH) { else if(obedit && obedit->type == OB_MESH) {
Mesh *me= (Mesh*)obedit->data; Mesh *me= (Mesh*)obedit->data;
struct BMEditMesh *em= me->edit_btmesh; struct BMEditMesh *em= me->edit_btmesh;
MTexPoly *tf; int sloppy= 1; /* partially selected face is ok */
if(em && EDBM_texFaceCheck(em)) { if(scene_use_new_shading_nodes(scene)) {
sima->image= NULL; /* new shading system, get image from material */
BMFace *efa = BM_get_actFace(em->bm, sloppy);
tf = EDBM_get_active_mtexpoly(em, NULL, 1); /* partially selected face is ok */ if(efa)
ED_object_get_active_image(obedit, efa->mat_nr, &sima->image, NULL, NULL);
}
else {
/* old shading system, we set texface */
MTexPoly *tf;
if(tf) { if(em && EDBM_texFaceCheck(em)) {
/* don't need to check for pin here, see above */ sima->image= NULL;
sima->image= tf->tpage;
if(sima->flag & SI_EDITTILE); tf = EDBM_get_active_mtexpoly(em, NULL, 1); /* partially selected face is ok */
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;
}
} }
} }
} }

@ -25,6 +25,7 @@ set(INC
../../blenlib ../../blenlib
../../blenloader ../../blenloader
../../imbuf ../../imbuf
../../gpu
../../makesdna ../../makesdna
../../makesrna ../../makesrna
../../nodes ../../nodes

@ -4,7 +4,7 @@ Import ('env')
sources = env.Glob('*.c') sources = env.Glob('*.c')
incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf' 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' incs += ' ../../windowmanager #intern/guardedalloc #extern/glew/include'
defs = [] defs = []
cf = [] cf = []

@ -90,6 +90,8 @@
#include "RNA_enum_types.h" #include "RNA_enum_types.h"
#include "GPU_material.h"
#include "node_intern.h" #include "node_intern.h"
static EnumPropertyItem socket_in_out_items[] = { 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) void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node)
{ {
int was_active_texture = (node->flag & NODE_ACTIVE_TEXTURE);
nodeSetActive(ntree, node); nodeSetActive(ntree, node);
if(node->type!=NODE_GROUP) { 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); 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); WM_main_add_notifier(NC_MATERIAL|ND_NODES, node->id);
} }
else if(ntree->type==NTREE_COMPOSIT) { else if(ntree->type==NTREE_COMPOSIT) {

@ -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 */ /* remove node */
node_remove_linked(ntree, node_prev); 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->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK;
but->poin= (char*)but; but->poin= (char*)but;
but->func_argN = arg; 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 *******************************/ /**************************** Node Tree Layout *******************************/

@ -41,12 +41,13 @@
#include "DNA_material_types.h" #include "DNA_material_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_property_types.h" #include "DNA_property_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h" #include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
#include "BKE_DerivedMesh.h" #include "BKE_DerivedMesh.h"
#include "BKE_effect.h" #include "BKE_effect.h"
@ -55,6 +56,7 @@
#include "BKE_paint.h" #include "BKE_paint.h"
#include "BKE_property.h" #include "BKE_property.h"
#include "BKE_tessmesh.h" #include "BKE_tessmesh.h"
#include "BKE_scene.h"
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BIF_glutil.h" #include "BIF_glutil.h"
@ -67,6 +69,7 @@
#include "GPU_material.h" #include "GPU_material.h"
#include "ED_mesh.h" #include "ED_mesh.h"
#include "ED_uvedit.h"
#include "view3d_intern.h" // own include #include "view3d_intern.h" // own include
@ -646,7 +649,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
ddm->release(ddm); 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; Mesh *me= ob->data;
@ -703,3 +706,179 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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);
}

@ -111,7 +111,7 @@
/* this condition has been made more complex since editmode can draw textures */ /* this condition has been made more complex since editmode can draw textures */
#define CHECK_OB_DRAWTEXTURE(vd, dt) \ #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)) (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX))
static void draw_bounding_volume(Scene *scene, Object *ob, char type); static void draw_bounding_volume(Scene *scene, Object *ob, char type);
@ -255,6 +255,8 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt)
return 0; return 0;
if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT)) if(ob==OBACT && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return 0; return 0;
if(scene_use_new_shading_nodes(scene))
return 0;
return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID); return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID);
} }

@ -2229,11 +2229,17 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
{ {
CustomDataMask mask= 0; 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; mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
if(scene->gm.matmode == GAME_MAT_GLSL) if(scene_use_new_shading_nodes(scene)) {
mask |= CD_MASK_ORCO; if(v3d->drawtype == OB_MATERIAL)
mask |= CD_MASK_ORCO;
}
else {
if(scene->gm.matmode == GAME_MAT_GLSL)
mask |= CD_MASK_ORCO;
}
} }
return mask; return mask;

@ -38,7 +38,9 @@
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h" #include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
#include "DNA_image_types.h" #include "DNA_image_types.h"
#include "DNA_space_types.h" #include "DNA_space_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
@ -54,12 +56,15 @@
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_library.h" #include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_report.h" #include "BKE_report.h"
#include "BKE_tessmesh.h" #include "BKE_tessmesh.h"
#include "ED_image.h" #include "ED_image.h"
#include "ED_mesh.h" #include "ED_mesh.h"
#include "ED_node.h"
#include "ED_uvedit.h" #include "ED_uvedit.h"
#include "ED_object.h" #include "ED_object.h"
#include "ED_screen.h" #include "ED_screen.h"
@ -96,9 +101,46 @@ int ED_uvedit_test(Object *obedit)
return ret; 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 ************************/ /************************* 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)
{ {
BMEditMesh *em; BMEditMesh *em;
BMFace *efa; BMFace *efa;
@ -119,35 +161,48 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
return; return;
} }
/* ensure we have a uv layer */ if(scene_use_new_shading_nodes(scene)) {
if(!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) { /* new shading system, assign image in material */
BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY); int sloppy= 1;
BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV); BMFace *efa= BM_get_actFace(em->bm, sloppy);
update= 1;
if(efa)
ED_object_assign_active_image(bmain, obedit, efa->mat_nr, ima);
} }
else {
/* old shading system, assign image to selected faces */
/* now assign to all visible faces */ /* ensure we have a uv layer */
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { if(!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) {
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY);
BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV);
if(uvedit_face_visible(scene, previma, efa, tf)) { update= 1;
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;
} }
/* now assign to all visible faces */
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
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;
}
}
/* 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);
} }
/* dotile - 1, set the tile flag (from the space image) /* dotile - 1, set the tile flag (from the space image)

@ -53,6 +53,7 @@
#include "BKE_customdata.h" #include "BKE_customdata.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_tessmesh.h" #include "BKE_tessmesh.h"
@ -83,6 +84,7 @@
static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
{ {
Main *bmain= CTX_data_main(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh; BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
BMFace *efa; BMFace *efa;
BMIter iter; BMIter iter;
@ -128,7 +130,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
} }
if(ima) if(ima)
ED_uvedit_assign_image(scene, obedit, ima, NULL); ED_uvedit_assign_image(bmain, scene, obedit, ima, NULL);
/* select new UV's */ /* select new UV's */
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) { BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {

@ -62,7 +62,7 @@
#include "BKE_material.h" #include "BKE_material.h"
#include "BKE_node.h" #include "BKE_node.h"
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_scene.h"
#include "BLI_threads.h" #include "BLI_threads.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"
@ -952,15 +952,17 @@ static struct GPUMaterialState {
} GMS = {NULL}; } GMS = {NULL};
/* fixed function material, alpha handed by caller */ /* 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); copy_v3_v3(smat->diff, &bmat->r);
smat->diff[3]= 1.0; smat->diff[3]= 1.0;
if(gamma) { if(gamma)
linearrgb_to_srgb_v3_v3(smat->diff, smat->diff); linearrgb_to_srgb_v3_v3(smat->diff, smat->diff);
}
zero_v4(smat->spec);
smat->hard= 0;
} }
else { else {
mul_v3_v3fl(smat->diff, &bmat->r, bmat->ref + bmat->emit); 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; GPUBlendMode alphablend;
int a; int a;
int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
int new_shading_nodes = scene_use_new_shading_nodes(scene);
/* initialize state */ /* initialize state */
memset(&GMS, 0, sizeof(GMS)); memset(&GMS, 0, sizeof(GMS));
@ -1032,7 +1035,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
/* no materials assigned? */ /* no materials assigned? */
if(ob->totcol==0) { 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! */ /* do material 1 too, for displists! */
memcpy(&GMS.matbuf[1], &GMS.matbuf[0], sizeof(GPUMaterialFixed)); 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++) { for(a=1; a<=ob->totcol; a++) {
/* find a suitable material */ /* find a suitable material */
ma= give_current_material(ob, a); 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; if(ma==NULL) ma= &defmaterial;
/* create glsl material if requested */ /* create glsl material if requested */
@ -1062,7 +1065,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O
} }
else { else {
/* fixed function opengl materials */ /* 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; alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA;
if(do_alpha_pass && GMS.alphapass) if(do_alpha_pass && GMS.alphapass)
@ -1223,6 +1226,7 @@ void GPU_end_object_materials(void)
int GPU_default_lights(void) int GPU_default_lights(void)
{ {
float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}, position[4];
int a, count = 0; int a, count = 0;
/* initialize */ /* initialize */
@ -1248,27 +1252,28 @@ int GPU_default_lights(void)
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); 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++) { for(a=0; a<8; a++) {
if(a<3) { if(a<3) {
if(U.light[a].flag) { if(U.light[a].flag) {
glEnable(GL_LIGHT0+a); 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++; count++;
} }
else else {
glDisable(GL_LIGHT0+a); 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 // clear stuff from other opengl lamp usage
glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0); glLightf(GL_LIGHT0+a, GL_SPOT_CUTOFF, 180.0);
glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0); glLightf(GL_LIGHT0+a, GL_CONSTANT_ATTENUATION, 1.0);

@ -1415,29 +1415,33 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
if(((GPUMaterial*)link->data)->scene == scene) if(((GPUMaterial*)link->data)->scene == scene)
return link->data; return link->data;
/* allocate material */
mat = GPU_material_construct_begin(ma); mat = GPU_material_construct_begin(ma);
mat->scene = scene; mat->scene = scene;
if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) { if(!(scene->gm.flag & GAME_GLSL_NO_NODES) && ma->nodetree && ma->use_nodes) {
/* create nodes */
ntreeGPUMaterialNodes(ma->nodetree, mat); ntreeGPUMaterialNodes(ma->nodetree, mat);
} }
else { else {
/* create material */
outlink = GPU_blender_material(mat, ma); outlink = GPU_blender_material(mat, ma);
GPU_material_output_link(mat, outlink); GPU_material_output_link(mat, outlink);
} }
if(gpu_do_color_management(mat)) if(!scene_use_new_shading_nodes(scene)) {
if(mat->outlink) if(gpu_do_color_management(mat))
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink); 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); 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 = MEM_callocN(sizeof(LinkData), "GPUMaterialLink");
link->data = mat; link->data = mat;
BLI_addtail(&ma->gpumaterial, link); BLI_addtail(&ma->gpumaterial, link);

@ -145,6 +145,8 @@ typedef struct SpaceButs {
void *path; /* runtime */ void *path; /* runtime */
int pathflag, dataicon; /* runtime */ int pathflag, dataicon; /* runtime */
ID *pinid; ID *pinid;
void *texuser;
} SpaceButs; } SpaceButs;
typedef struct SpaceSeq { typedef struct SpaceSeq {

@ -575,6 +575,7 @@ static int rna_SceneRender_file_ext_length(PointerRNA *ptr)
static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str) static void rna_SceneRender_file_ext_get(PointerRNA *ptr, char *str)
{ {
RenderData *rd= (RenderData*)ptr->data; RenderData *rd= (RenderData*)ptr->data;
str[0]= '\0';
BKE_add_image_extension(str, rd->imtype); BKE_add_image_extension(str, rd->imtype);
} }

@ -102,7 +102,8 @@ EnumPropertyItem viewport_shade_items[] = {
{OB_BOUNDBOX, "BOUNDBOX", ICON_BBOX, "Bounding Box", "Display the object's local bounding boxes only"}, {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_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_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"}, {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"},
{0, NULL, 0, NULL, NULL}}; {0, NULL, 0, NULL, NULL}};
@ -114,13 +115,14 @@ EnumPropertyItem viewport_shade_items[] = {
#include "BLI_math.h" #include "BLI_math.h"
#include "BKE_screen.h"
#include "BKE_animsys.h" #include "BKE_animsys.h"
#include "BKE_brush.h" #include "BKE_brush.h"
#include "BKE_colortools.h" #include "BKE_colortools.h"
#include "BKE_context.h" #include "BKE_context.h"
#include "BKE_depsgraph.h" #include "BKE_depsgraph.h"
#include "BKE_paint.h" #include "BKE_paint.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "ED_image.h" #include "ED_image.h"
#include "ED_node.h" #include "ED_node.h"
@ -462,9 +464,11 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C
RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID); RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID);
RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE); RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE);
if(type->view_draw) { if(scene_use_new_shading_nodes(scene))
RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_MATERIAL);
if(type->view_draw)
RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER); RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER);
}
RNA_enum_item_end(&item, &totitem); RNA_enum_item_end(&item, &totitem);
*free= 1; *free= 1;

@ -465,6 +465,9 @@ void RNA_api_ui_layout(StructRNA *srna)
parm= RNA_def_pointer(func, "socket", "NodeSocket", "", ""); parm= RNA_def_pointer(func, "socket", "NodeSocket", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED); 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"); func= RNA_def_function(srna, "template_keymap_item_properties", "uiTemplateKeymapItemProperties");
parm= RNA_def_pointer(func, "item", "KeyMapItem", "", ""); parm= RNA_def_pointer(func, "item", "KeyMapItem", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL);

@ -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]); 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) void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, int do_outputs)
{ {
bNodeExec *nodeexec; bNodeExec *nodeexec;

@ -393,6 +393,8 @@ void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *p
void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){} 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 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 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 uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){}
void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){} 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){} void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){}