Texturing: texture and 3d view draw type changes, these should only have any

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
This commit is contained in:
Brecht Van Lommel 2011-11-08 13:07:16 +00:00
parent 19df3147f6
commit 28ee0f9218
Notes: blender-bot 2023-02-14 00:29:15 +01:00
Referenced by commit 92b342d30d, Fix logic for pinning textures users from context
33 changed files with 1560 additions and 203 deletions

View 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);

View 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);

View 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;

View 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;

View 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

View 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;

View File

@ -33,19 +33,26 @@
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);

View 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);

View 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);

View 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);

View 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)

View 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

View File

@ -54,7 +54,6 @@
#include "BKE_screen.h"
#include "BKE_texture.h"
#include "RNA_access.h"
#include "ED_armature.h"
@ -66,13 +65,6 @@
#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;
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;
}
/* 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);
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;
RNA_id_pointer_create(&tex->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;
}
}
/* 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;
}
}
/* 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);
/* 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);
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 world */
if((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
wo= path->ptr[path->len-1].data;
if(ma) {
tex= give_current_material_texture(ma);
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;
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 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(la) {
tex= give_current_lamp_texture(la);
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 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 material */
if(buttons_context_path_material(path, 1)) {
ma= path->ptr[path->len-1].data;
if(ma) {
tex= give_current_material_texture(ma);
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;
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;

View File

@ -31,14 +31,20 @@
#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);

View File

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

View 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;
}

View File

@ -47,7 +47,10 @@
#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;
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;
tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
if(tf) {
/* don't need to check for pin here, see above */
sima->image= tf->tpage;
if(em && EM_texFaceCheck(em)) {
sima->image= NULL;
if(sima->flag & SI_EDITTILE);
else sima->curtile= tf->tile;
tf = EM_get_active_mtface(em, NULL, NULL, sloppy);
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;
}
}
}

View File

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

View 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 = []

View 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) {

View 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 *******************************/

View File

@ -40,11 +40,12 @@
#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);
}

View File

@ -108,7 +108,7 @@
/* 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);
}

View 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;

View 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"
@ -50,11 +52,16 @@
#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);
}
/* 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;
}
update = 1;
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;
}
}
/* and update depdency graph */
if(update)
DAG_id_tag_update(obedit->data, 0);
/* 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;
update = 1;
}
}
/* and update depdency graph */
if(update)
DAG_id_tag_update(obedit->data, 0);
}
BKE_mesh_end_editmesh(obedit->data, em);
}

View 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) {

View 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);

View 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);

View File

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

View 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;

View 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);

View 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;

View 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){}