diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-08-28 12:53:36 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2007-08-28 12:53:36 +0400 |
commit | f118bebc361ca0efd812c26f1f8577414c9693e0 (patch) | |
tree | b3208d54041a5c4166c71cac265ae6367cd362e1 | |
parent | 2252b636a3887ec82e2b06212a752ac193219bea (diff) |
Textured drawing in Edit Mode
=============================
- In textured drawmode it now draws the texture, with solid mode lighting.
- UVs and vertex colors for subsurf are not computed incremental yet, so
editing in textured drawmode then may not be as fast as the other modes.
Implementation Notes:
- Added textured drawing functions to the editmesh and subsurf derivedmeshes.
- Removed some unused, legacy subsurf code that directly used Mesh.
- Restructured texture drawing a bit to make it more clear and allow for
editmode drawing.
(Peach feature request)
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 168 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 374 | ||||
-rw-r--r-- | source/blender/include/BDR_drawmesh.h | 3 | ||||
-rw-r--r-- | source/blender/src/drawmesh.c | 391 | ||||
-rw-r--r-- | source/blender/src/drawobject.c | 33 |
5 files changed, 592 insertions, 377 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index be1d39d6c8c..25826037d5f 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -701,6 +701,172 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us } } +static void emDM_drawFacesTex_common(DerivedMesh *dm, + int (*drawParams)(MTFace *tface, MCol *mcol, int matnr), + int (*drawParamsMapped)(void *userData, int index), + void *userData) +{ + EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; + EditMesh *em= emdm->em; + float (*vertexCos)[3]= emdm->vertexCos; + float (*vertexNos)[3]= emdm->vertexNos; + EditFace *efa; + int i; + + if (vertexCos) { + EditVert *eve; + + for (i=0,eve=em->verts.first; eve; eve= eve->next) + eve->tmp.l = (long) i++; + + for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { + MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); + unsigned char *cp= NULL; + int drawSmooth= (efa->flag & ME_SMOOTH); + int flag; + + if(drawParams) + flag= drawParams(tf, mcol, efa->mat_nr); + else if(drawParamsMapped) + flag= drawParamsMapped(userData, i); + else + flag= 1; + + if(flag != 0) { /* flag 0 == the face is hidden or invisible */ + if (flag==1 && mcol) + cp= (unsigned char*)mcol; + + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + if (!drawSmooth) { + glNormal3fv(emdm->faceNos[i]); + + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + + if(efa->v4) { + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } + } else { + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3fv(vertexNos[(int) efa->v1->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v1->tmp.l]); + + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3fv(vertexNos[(int) efa->v2->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v2->tmp.l]); + + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3fv(vertexNos[(int) efa->v3->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v3->tmp.l]); + + if(efa->v4) { + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3fv(vertexNos[(int) efa->v4->tmp.l]); + glVertex3fv(vertexCos[(int) efa->v4->tmp.l]); + } + } + glEnd(); + } + } + } else { + for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) { + MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL); + unsigned char *cp= NULL; + int drawSmooth= (efa->flag & ME_SMOOTH); + int flag; + + if(drawParams) + flag= drawParams(tf, mcol, efa->mat_nr); + else if(drawParamsMapped) + flag= drawParamsMapped(userData, i); + else + flag= 1; + + if(flag != 0) { /* flag 0 == the face is hidden or invisible */ + if (flag==1 && mcol) + cp= (unsigned char*)mcol; + + glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT); + + glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); + if (!drawSmooth) { + glNormal3fv(efa->n); + + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(efa->v1->co); + + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3fv(efa->v2->co); + + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3fv(efa->v3->co); + + if(efa->v4) { + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3fv(efa->v4->co); + } + } else { + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3fv(efa->v1->no); + glVertex3fv(efa->v1->co); + + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3fv(efa->v2->no); + glVertex3fv(efa->v2->co); + + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3fv(efa->v3->no); + glVertex3fv(efa->v3->co); + + if(efa->v4) { + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3fv(efa->v4->no); + glVertex3fv(efa->v4->co); + } + } + glEnd(); + } + } + } +} + +static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) +{ + emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); +} + +static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) +{ + emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); +} + static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm; @@ -946,6 +1112,8 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob, emdm->dm.drawMappedEdges = emDM_drawMappedEdges; emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp; emdm->dm.drawMappedFaces = emDM_drawMappedFaces; + emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex; + emdm->dm.drawFacesTex = emDM_drawFacesTex; emdm->dm.drawUVEdges = emDM_drawUVEdges; emdm->dm.release = emDM_release; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 8fc92829258..d30301dc1a4 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -75,8 +75,6 @@ struct CCGDerivedMesh { CCGSubSurf *ss; int drawInteriorEdges, useSubsurfUv; - Mesh *me; - struct {int startVert; CCGVert *vert;} *vertMap; struct {int startVert; int startEdge; CCGEdge *edge;} *edgeMap; struct {int startVert; int startEdge; @@ -335,7 +333,6 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n); MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); - if(!dmtface || !tface) return; @@ -1095,7 +1092,7 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) /* this vert comes from edge data */ CCGEdge *e; int edgeSize = ccgSubSurf_getEdgeSize(ss); - int x; + int x, *edgeFlag; unsigned int flags = 0; i = (edgeNum - ccgdm->edgeMap[0].startEdge) / (edgeSize - 1); @@ -1109,24 +1106,12 @@ static void ccgDM_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) med->v1 = getEdgeIndex(ss, e, x, edgeSize); med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); - if(ccgdm->me) { - int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e); - - if(edgeIdx!=-1) { - MEdge *medge = ccgdm->me->medge; - MEdge *origMed = &medge[edgeIdx]; - - flags |= (origMed->flag & (ME_SEAM | ME_SHARP)) - | ME_EDGEDRAW | ME_EDGERENDER; - } - } else { - int *edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS); - if(edgeFlag) - flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) - | ME_EDGEDRAW | ME_EDGERENDER; - else - flags |= ME_EDGEDRAW | ME_EDGERENDER; - } + edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS); + if(edgeFlag) + flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) + | ME_EDGEDRAW | ME_EDGERENDER; + else + flags |= ME_EDGEDRAW | ME_EDGERENDER; med->flag = flags; } @@ -1147,7 +1132,7 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) int grid; int x, y; int lastface = ccgSubSurf_getNumFaces(ss) - 1; - int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); + char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); memset(mf, 0, sizeof(*mf)); @@ -1169,7 +1154,7 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize); mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize); - if(faceFlags) mf->flag = faceFlags[i]; + if(faceFlags) mf->flag = faceFlags[i*4]; else mf->flag = ME_SMOOTH; } @@ -1236,11 +1221,8 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) int gridSize = ccgSubSurf_getGridSize(ss); int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; - MEdge *origEdges = NULL; int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS); - if(ccgdm->me) origEdges = ccgdm->me->medge; - totface = ccgSubSurf_getNumFaces(ss); for(index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; @@ -1292,14 +1274,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) if(!ccgSubSurf_getEdgeNumFaces(ss, e)) flags |= ME_LOOSEEDGE; - if(origEdges){ - if(edgeIdx != -1) { - MEdge *origMed = &origEdges[edgeIdx]; - - flags |= (origMed->flag & (ME_SEAM | ME_SHARP)) - | ME_EDGEDRAW | ME_EDGERENDER; - } - } else if(edgeFlags) { + if(edgeFlags) { if(edgeIdx != -1) { flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER; @@ -1327,10 +1302,7 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) int gridSize = ccgSubSurf_getGridSize(ss); int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; - MFace *origFaces = NULL; - int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); - - if(ccgdm->me) origFaces = ccgdm->me->mface; + char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); totface = ccgSubSurf_getNumFaces(ss); for(index = 0; index < totface; index++) { @@ -1339,16 +1311,6 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) int mat_nr = 0; int flag = ME_SMOOTH; /* assume face is smooth by default */ - if(!faceFlags) { - if(origFaces) { - int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f); - MFace *origMFace = &origFaces[origIdx]; - - mat_nr = origMFace->mat_nr; - flag = origMFace->flag; - } - } - for(S = 0; S < numVerts; S++) { for(y = 0; y < gridSize - 1; y++) { for(x = 0; x < gridSize - 1; x++) { @@ -1362,7 +1324,7 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize); mf->mat_nr = mat_nr; - if(faceFlags) mf->flag = faceFlags[index]; + if(faceFlags) mf->flag = faceFlags[index*4]; else mf->flag = flag; i++; @@ -1623,28 +1585,51 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) { ccgEdgeIterator_free(ei); } +static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) +{ + float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; + float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; + float no[3]; + + no[0] = b_dY*a_cZ - b_dZ*a_cY; + no[1] = b_dZ*a_cX - b_dX*a_cZ; + no[2] = b_dX*a_cY - b_dY*a_cX; + + /* don't normalize, GL_NORMALIZE is be enabled */ + glNormal3fv(no); +} + /* Only used by non-editmesh types */ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); int gridSize = ccgSubSurf_getGridSize(ss); - MFace *mface = ccgdm->me->mface; + char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS); for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f); - MFace *mf = &mface[index]; + int drawSmooth, mat_nr; + + if(faceFlags) { + drawSmooth = (faceFlags[index*4] & ME_SMOOTH); + mat_nr= faceFlags[index*4 + 1]; + } + else { + drawSmooth = 1; + mat_nr= 0; + } - if (!setMaterial(mf->mat_nr+1)) + if (!setMaterial(mat_nr+1)) continue; - glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT); + glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - if (mf->flag&ME_SMOOTH) { + if (drawSmooth) { for (y=0; y<gridSize-1; y++) { glBegin(GL_QUAD_STRIP); for (x=0; x<gridSize; x++) { @@ -1666,14 +1651,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) { float *b = faceGridData[(y+0)*gridSize + x + 1].co; float *c = faceGridData[(y+1)*gridSize + x + 1].co; float *d = faceGridData[(y+1)*gridSize + x].co; - float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; - float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; - float no[3]; - no[0] = b_dY*a_cZ - b_dZ*a_cY; - no[1] = b_dZ*a_cX - b_dX*a_cZ; - no[2] = b_dX*a_cY - b_dY*a_cX; - glNormal3fv(no); + ccgDM_glNormalFast(a, b, c, d); glVertex3fv(d); glVertex3fv(c); @@ -1753,132 +1732,151 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned ch ccgFaceIterator_free(fi); } -static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(MTFace *tface, MCol *mcol, int matnr)) +static void ccgDM_drawFacesTex_common(DerivedMesh *dm, + int (*drawParams)(MTFace *tface, MCol *mcol, int matnr), + int (*drawParamsMapped)(void *userData, int index), + void *userData) { - /* unimplemented, no textures in editmode anyway */ -} -static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData) -{ - /* unfinished code, no textures in editmode anyway */ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; - CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - MFace *mface = ccgdm->me->mface; - MCol *mcol = ccgdm->me->mcol; -// float uv[4][2]; -// float col[4][3]; + MCol *mcol = DM_get_face_data_layer(dm, CD_MCOL); + MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE); + char *faceFlags = DM_get_face_data_layer(dm, CD_FLAGS); + int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss); + int gridFaces = gridSize - 1; + unsigned char *cp; - glBegin(GL_QUADS); - for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); + totface = ccgSubSurf_getNumFaces(ss); + for(i = 0; i < totface; i++) { + CCGFace *f = ccgdm->faceMap[i].face; int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f); - int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f); - MFace *mf = &mface[index]; - unsigned char *cp= NULL; - int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f); - int flag = (findex == -1)? 0: setDrawParams(userData, findex); + int drawSmooth, index = ccgDM_getFaceMapIndex(ccgdm, ss, f); + int origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f); + int mat_nr; + + if(faceFlags) { + drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH); + mat_nr= faceFlags[origIndex*4 + 1]; + } + else { + drawSmooth = 1; + mat_nr= 0; + } - if (flag==0) + if(drawParams) + flag = drawParams(tf, mcol, mat_nr); + else + flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1; + + if (flag == 0) { /* flag 0 == the face is hidden or invisible */ + if(tf) tf += gridFaces*gridFaces*numVerts; + if(mcol) mcol += gridFaces*gridFaces*numVerts*4; continue; - else if (flag==1 && mcol) - cp= (unsigned char*) &mcol[index*4]; + } + + /* flag 1 == use vertex colors */ + cp= (flag==1 && mcol)? (unsigned char*)&mcol[i*4]: NULL; for (S=0; S<numVerts; S++) { VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); - for (y=0; y<gridSize-1; y++) { - for (x=0; x<gridSize-1; x++) { - VertData *a = &faceGridData[(y+0)*gridSize + x + 0]; - VertData *b = &faceGridData[(y+0)*gridSize + x + 1]; - VertData *c = &faceGridData[(y+1)*gridSize + x + 1]; - VertData *d = &faceGridData[(y+1)*gridSize + x + 0]; + VertData *a, *b; - if (!(mf->flag&ME_SMOOTH)) { - float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2]; - float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[2]; - float no[3]; + if (drawSmooth) { + glShadeModel(GL_SMOOTH); + for (y=0; y<gridFaces; y++) { + glBegin(GL_QUAD_STRIP); + for (x=0; x<gridFaces; x++) { + a = &faceGridData[(y+0)*gridSize + x]; + b = &faceGridData[(y+1)*gridSize + x]; - no[0] = b_dY*a_cZ - b_dZ*a_cY; - no[1] = b_dZ*a_cX - b_dX*a_cZ; - no[2] = b_dX*a_cY - b_dY*a_cX; + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glNormal3fv(a->no); + glVertex3fv(a->co); - glNormal3fv(no); + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glNormal3fv(b->no); + glVertex3fv(b->co); + + if(x != gridFaces-1) { + if(tf) tf++; + if(cp) cp += 16; + } } -// if (tf) glTexCoord2fv(tf->uv[0]); -// if (cp) glColor3ub(cp[3], cp[2], cp[1]); -// if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no); -// glVertex3fv(mvert[mf->v1].co); + a = &faceGridData[(y+0)*gridSize + x]; + b = &faceGridData[(y+1)*gridSize + x]; -/* - { - float x_v = (float) fx/(gridSize-1); - float y_v = (float) fy/(gridSize-1); - float data[6]; + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3fv(a->no); + glVertex3fv(a->co); - for (k=0; k<numDataComponents; k++) { - data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + - (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v; - } -*/ - -// if (cp) glColor3ub(cp[3], cp[2], cp[1]); - if (mf->flag&ME_SMOOTH) glNormal3fv(d->no); - glVertex3fv(d->co); -// if (cp) glColor3ub(cp[7], cp[6], cp[5]); - if (mf->flag&ME_SMOOTH) glNormal3fv(c->no); - glVertex3fv(c->co); -// if (cp) glColor3ub(cp[11], cp[10], cp[9]); - if (mf->flag&ME_SMOOTH) glNormal3fv(b->no); + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3fv(b->no); glVertex3fv(b->co); -// if (cp) glColor3ub(cp[15], cp[14], cp[13]); - if (mf->flag&ME_SMOOTH) glNormal3fv(a->no); - glVertex3fv(a->co); + + if(tf) tf++; + if(cp) cp += 16; + + glEnd(); + } + } else { + glShadeModel(GL_FLAT); + glBegin(GL_QUADS); + for (y=0; y<gridFaces; y++) { + for (x=0; x<gridFaces; x++) { + float *a = faceGridData[(y+0)*gridSize + x].co; + float *b = faceGridData[(y+0)*gridSize + x + 1].co; + float *c = faceGridData[(y+1)*gridSize + x + 1].co; + float *d = faceGridData[(y+1)*gridSize + x].co; + + ccgDM_glNormalFast(a, b, c, d); + + if(tf) glTexCoord2fv(tf->uv[1]); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3fv(d); + + if(tf) glTexCoord2fv(tf->uv[2]); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3fv(c); + + if(tf) glTexCoord2fv(tf->uv[3]); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3fv(b); + + if(tf) glTexCoord2fv(tf->uv[0]); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3fv(a); + + if(tf) tf++; + if(cp) cp += 16; + } } + glEnd(); } } } - glEnd(); +} - ccgFaceIterator_free(fi); -/* - MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm; - Mesh *me = mdm->me; - MVert *mvert= mdm->verts; - MFace *mface= me->mface; - MTFace *tface = me->mtface; - float *nors = mdm->nors; - int a; - - for (a=0; a<me->totface; a++) { - MFace *mf= &mface[a]; - if (tf) glTexCoord2fv(tf->uv[1]); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no); - glVertex3fv(mvert[mf->v2].co); - - if (tf) glTexCoord2fv(tf->uv[2]); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no); - glVertex3fv(mvert[mf->v3].co); - - if(mf->v4) { - if (tf) glTexCoord2fv(tf->uv[3]); - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no); - glVertex3fv(mvert[mf->v4].co); - } - glEnd(); - } -*/ +static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) +{ + ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); +} + +static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) +{ + ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData); } + static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); int i, gridSize = ccgSubSurf_getGridSize(ss); - int *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); + char *faceFlags = dm->getFaceDataArray(dm, CD_FLAGS); for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) { CCGFace *f = ccgFaceIterator_getCurrent(fi); @@ -1888,7 +1886,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u origIndex = (int)ccgSubSurf_getFaceFaceHandle(ss, f); - if(faceFlags) drawSmooth = (faceFlags[origIndex] & ME_SMOOTH); + if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH); else drawSmooth = 1; if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) { @@ -2035,7 +2033,7 @@ static void ccgDM_release(DerivedMesh *dm) { static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, - int useSubsurfUv, Mesh *me, + int useSubsurfUv, DerivedMesh *dm) { CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); @@ -2046,7 +2044,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int i; int vertNum, edgeNum, faceNum; int *vertOrigIndex, *edgeOrigIndex, *faceOrigIndex; - int *faceFlags, *edgeFlags; + int *edgeFlags; + char *faceFlags; int edgeSize; int gridSize; int gridFaces; @@ -2059,20 +2058,14 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, MFace *mface = NULL; FaceVertWeight *qweight, *tweight; - if(dm) { - DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss), - ccgSubSurf_getNumFinalEdges(ss), - ccgSubSurf_getNumFinalFaces(ss)); - DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL); - DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL); - - CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY); - CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY); - } else { - DM_init(&ccgdm->dm, ccgSubSurf_getNumFinalVerts(ss), - ccgSubSurf_getNumFinalEdges(ss), - ccgSubSurf_getNumFinalFaces(ss)); - } + DM_from_template(&ccgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss), + ccgSubSurf_getNumFinalEdges(ss), + ccgSubSurf_getNumFinalFaces(ss)); + DM_add_face_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL); + DM_add_edge_layer(&ccgdm->dm, CD_FLAGS, CD_CALLOC, NULL); + + CustomData_set_layer_flag(&ccgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY); + CustomData_set_layer_flag(&ccgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY); ccgdm->dm.getMinMax = ccgDM_getMinMax; ccgdm->dm.getNumVerts = ccgDM_getNumVerts; @@ -2105,6 +2098,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex; ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex; + /* todo: drawUVEdges */ ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp; ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges; @@ -2114,7 +2108,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->ss = ss; ccgdm->drawInteriorEdges = drawInteriorEdges; ccgdm->useSubsurfUv = useSubsurfUv; - ccgdm->me = me; totvert = ccgSubSurf_getNumVerts(ss); ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap"); @@ -2159,15 +2152,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, edgeNum = 0; faceNum = 0; - if(dm) { - mvert = dm->getVertArray(dm); - medge = dm->getEdgeArray(dm); - mface = dm->getFaceArray(dm); - } else if(me) { - mvert = me->mvert; - medge = me->medge; - mface = me->mface; - } + mvert = dm->getVertArray(dm); + medge = dm->getEdgeArray(dm); + mface = dm->getFaceArray(dm); vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX); @@ -2277,7 +2264,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, } } - faceFlags[index] = mface[origIndex].flag; + faceFlags[index*4] = mface[origIndex].flag; + faceFlags[index*4 + 1] = mface[origIndex].mat_nr; edgeNum += numFinalEdges; } @@ -2381,7 +2369,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived( return (DerivedMesh *)getCCGDerivedMesh(smd->emCache, drawInteriorEdges, - useSubsurfUv, NULL, dm); + useSubsurfUv, dm); } else if(useRenderParams) { /* Do not use cache in render mode. */ CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, useSimple); @@ -2418,8 +2406,13 @@ struct DerivedMesh *subsurf_make_derived_from_derived( ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); + return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges, useSubsurfUv, dm); + + /*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache, + drawInteriorEdges, + useSubsurfUv, dm);*/ } else { if (smd->mCache && isFinalCalc) { ccgSubSurf_free(smd->mCache); @@ -2429,6 +2422,11 @@ struct DerivedMesh *subsurf_make_derived_from_derived( ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); + /*smd->mCache = ss; + result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache, + drawInteriorEdges, + useSubsurfUv, dm);*/ + result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges, useSubsurfUv, dm); diff --git a/source/blender/include/BDR_drawmesh.h b/source/blender/include/BDR_drawmesh.h index 60c87308e20..998cadc18a3 100644 --- a/source/blender/include/BDR_drawmesh.h +++ b/source/blender/include/BDR_drawmesh.h @@ -36,6 +36,7 @@ struct Image; struct MTFace; struct Object; +struct DerivedMesh; struct Mesh; struct EdgeHash; @@ -75,7 +76,7 @@ int set_tpage(struct MTFace *tface); void texpaint_enable_mipmap(void); void texpaint_disable_mipmap(void); -void draw_tface_mesh(struct Object *ob, struct Mesh *me, int dt); +void draw_mesh_textured(struct Object *ob, struct DerivedMesh *dm, int facesel); struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me); void init_realtime_GL(void); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index 6307307345b..e275a3c5425 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_edgehash.h" +#include "BLI_editVert.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -66,7 +67,7 @@ #include "BKE_property.h" #include "BKE_utildefines.h" -#include "BIF_resources.h" +#include "BIF_editmesh.h" #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_mywindow.h" @@ -941,25 +942,81 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac /* Icky globals, fix with userdata parameter */ -static Object *g_draw_tface_mesh_ob = NULL; -static int g_draw_tface_mesh_islight = 0; -static int g_draw_tface_mesh_istex = 0; -static unsigned char g_draw_tface_mesh_obcol[4]; +struct TextureDrawState { + Object *ob; + int islit, istex; + unsigned char obcol[4]; +} Gtexdraw = {NULL, 0, 0, {0, 0, 0, 0}}; + +static void draw_textured_begin(Object *ob) +{ + unsigned char obcol[4]; + int istex, solidtex= 0; + + if(G.vd->drawtype==OB_SOLID || ob==G.obedit) { + /* draw with default lights in solid draw mode and edit mode */ + solidtex= 1; + Gtexdraw.islit= -1; + } + else + /* draw with lights in the scene otherwise */ + Gtexdraw.islit= set_gl_light(ob); + + obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); + obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); + obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255); + obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255); + + glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + if(solidtex || G.vd->drawtype==OB_TEXTURE) istex= 1; + else istex= 0; + + Gtexdraw.ob = ob; + Gtexdraw.istex = istex; + memcpy(Gtexdraw.obcol, obcol, sizeof(obcol)); + set_draw_settings_cached(1, 0, 0, Gtexdraw.islit, 0, 0, 0); + + glShadeModel(GL_SMOOTH); +} + +static void draw_textured_end() +{ + /* switch off textures */ + set_tpage(0); + + glShadeModel(GL_FLAT); + glDisable(GL_CULL_FACE); + + /* XXX, bad patch - default_gl_light() calls + * glLightfv(GL_LIGHT_POSITION, ...) which + * is transformed by the current matrix... we + * need to make sure that matrix is identity. + * + * It would be better if drawmesh.c kept track + * of and restored the light settings it changed. + * - zr + */ + glPushMatrix(); + glLoadIdentity(); + default_gl_light(); + glPopMatrix(); +} + static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) { if (tface && (tface->mode&TF_INVISIBLE)) return 0; - if (tface && set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) { + if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) { glColor3ub(0xFF, 0x00, 0xFF); return 2; /* Don't set color */ } else if (tface && tface->mode&TF_OBCOL) { - glColor3ubv(g_draw_tface_mesh_obcol); + glColor3ubv(Gtexdraw.obcol); return 2; /* Don't set color */ } else if (!mcol) { if (tface) glColor3f(1.0, 1.0, 1.0); else { - Material *ma= give_current_material(g_draw_tface_mesh_ob, matnr+1); + Material *ma= give_current_material(Gtexdraw.ob, matnr+1); if(ma) glColor3f(ma->r, ma->g, ma->b); else glColor3f(1.0, 1.0, 1.0); } @@ -980,6 +1037,24 @@ static int draw_tface_mapped__set_draw(void *userData, int index) return draw_tface__set_draw(tface, mcol, matnr); } +static int draw_em_tf_mapped__set_draw(void *userData, int index) +{ + EditMesh *em = userData; + EditFace *efa = EM_get_face_for_index(index); + MTFace *tface; + MCol *mcol; + int matnr; + + if (efa==NULL || efa->h) + return 0; + + tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL); + matnr = efa->mat_nr; + + return draw_tface__set_draw(tface, mcol, matnr); +} + static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r) { Mesh *me = (Mesh*)userData; @@ -994,199 +1069,158 @@ static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot return 1; } -void draw_tface_mesh(Object *ob, Mesh *me, int dt) -/* maximum dt (drawtype): exactly according values that have been set */ +static void draw_game_text_mesh(Object *ob, Mesh *me) { - unsigned char obcol[4]; - int a; - short istex, solidtex=0; - DerivedMesh *dm; - - if(me==NULL) return; + DerivedMesh *ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); + MFace *mface= me->mface; + MTFace *tface= me->mtface; + MCol *mcol= me->mcol; /* why does mcol exist? */ + bProperty *prop = get_property(ob, "Text"); + int a, start= 0, totface= me->totface; + + tface+= start; + mcol+= start*4; + for (a=start; a<totface; a++, tface++, mcol+=4) { + MFace *mf= &mface[a]; + int mode= tface->mode; + int matnr= mf->mat_nr; + int mf_smooth= mf->flag & ME_SMOOTH; + + if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) { + int badtex= set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE); + float v1[3], v2[3], v3[3], v4[3]; + char string[MAX_PROPSTRING]; + int characters, index; + ImBuf *ibuf; + float curpos; + + if (badtex) + continue; + + ddm->getVertCo(ddm, mf->v1, v1); + ddm->getVertCo(ddm, mf->v2, v2); + ddm->getVertCo(ddm, mf->v3, v3); + if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4); + + // The BM_FONT handling code is duplicated in the gameengine + // Search for 'Frank van Beek' ;-) + // string = "Frank van Beek"; + + set_property_valstr(prop, string); + characters = strlen(string); + + ibuf= BKE_image_get_ibuf(tface->tpage, NULL); + if (ibuf == NULL) { + characters = 0; + } - dm = mesh_get_derived_final(ob, get_viewedit_datamask()); + if (!mf_smooth) { + float nor[3]; - glShadeModel(GL_SMOOTH); + CalcNormFloat(v1, v2, v3, nor); - /* option to draw solid texture with default lights */ - if(dt>OB_WIRE && G.vd->drawtype==OB_SOLID) { - solidtex= 1; - g_draw_tface_mesh_islight= -1; - } - else - g_draw_tface_mesh_islight= set_gl_light(ob); + glNormal3fv(nor); + } + + curpos= 0.0; + glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); + for (index = 0; index < characters; index++) { + float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; + int character = string[index]; + char *cp= NULL; + + // lets calculate offset stuff + // space starts at offset 1 + // character = character - ' ' + 1; + + matrixGlyph(ibuf, character, & centerx, ¢ery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance); + movex+= curpos; + + if (tface->mode & TF_OBCOL) + glColor3ubv(Gtexdraw.obcol); + else if (me->mcol) cp= (char *)mcol; + else glColor3ub(255, 255, 255); + + glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[3], cp[2], cp[1]); + glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]); + + glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[7], cp[6], cp[5]); + glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]); - obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); - obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); - obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255); - obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255); + glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[11], cp[10], cp[9]); + glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]); - /* first all texture polys */ + if(mf->v4) { + glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy); + if (cp) glColor3ub(cp[15], cp[14], cp[13]); + glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]); + } + + curpos+= advance; + } + glEnd(); + } + } + + ddm->release(ddm); +} + +void draw_mesh_textured(Object *ob, DerivedMesh *dm, int faceselect) +{ + Mesh *me= ob->data; + int editing= 0; + /* correct for negative scale */ if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); else glFrontFace(GL_CCW); - glCullFace(GL_BACK); glEnable(GL_CULL_FACE); - if(solidtex || G.vd->drawtype==OB_TEXTURE) istex= 1; - else istex= 0; - - g_draw_tface_mesh_ob = ob; - g_draw_tface_mesh_istex = istex; - memcpy(g_draw_tface_mesh_obcol, obcol, sizeof(obcol)); - set_draw_settings_cached(1, 0, 0, g_draw_tface_mesh_islight, 0, 0, 0); - - if(dt > OB_SOLID || g_draw_tface_mesh_islight==-1) { - bProperty *prop = get_property(ob, "Text"); - int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0)); + /* draw the textured mesh */ + draw_textured_begin(ob); #ifdef WITH_VERSE - if(me->vnode) { - /* verse-blender doesn't support uv mapping of textures yet */ - dm->drawFacesTex(dm, NULL); - } - else if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) { -#else - if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) { -#endif + if(me->vnode) { + /* verse-blender doesn't support uv mapping of textures yet */ + dm->drawFacesTex(dm, NULL); + } + else { +#endif + if(G.obedit) + dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, G.editMesh); + else if(faceselect) { if(G.f & G_WEIGHTPAINT) - dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, (void*)me, 1); + dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1); else - dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, (void*)me); + dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me); } else dm->drawFacesTex(dm, draw_tface__set_draw); +#ifdef WITH_VERSE + } +#endif - /* drawing game engine text hack */ - if (!editing && prop && me->mtface) { - DerivedMesh *ddm = mesh_get_derived_deform(ob, CD_MASK_BAREMESH); - MFace *mface= me->mface; - MTFace *tface= me->mtface; - MCol *mcol= me->mcol; /* why does mcol exist? */ - int start= 0, totface= me->totface; - - tface+= start; - mcol+= start*4; - for (a=start; a<totface; a++, tface++, mcol+=4) { - MFace *mf= &mface[a]; - int mode= tface->mode; - int matnr= mf->mat_nr; - int mf_smooth= mf->flag & ME_SMOOTH; - - if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) { - int badtex= set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE); - float v1[3], v2[3], v3[3], v4[3]; - char string[MAX_PROPSTRING]; - int characters, index; - ImBuf *ibuf; - float curpos; - - if (badtex) - continue; - - ddm->getVertCo(ddm, mf->v1, v1); - ddm->getVertCo(ddm, mf->v2, v2); - ddm->getVertCo(ddm, mf->v3, v3); - if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4); - - // The BM_FONT handling code is duplicated in the gameengine - // Search for 'Frank van Beek' ;-) - // string = "Frank van Beek"; - - set_property_valstr(prop, string); - characters = strlen(string); - - ibuf= BKE_image_get_ibuf(tface->tpage, NULL); - if (ibuf == NULL) { - characters = 0; - } - - if (!mf_smooth) { - float nor[3]; - - CalcNormFloat(v1, v2, v3, nor); - - glNormal3fv(nor); - } - - curpos= 0.0; - glBegin(mf->v4?GL_QUADS:GL_TRIANGLES); - for (index = 0; index < characters; index++) { - float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; - int character = string[index]; - char *cp= NULL; - - // lets calculate offset stuff - // space starts at offset 1 - // character = character - ' ' + 1; - - matrixGlyph(ibuf, character, & centerx, ¢ery, &sizex, &sizey, &transx, &transy, &movex, &movey, &advance); - movex+= curpos; - - if (tface->mode & TF_OBCOL) glColor3ubv(obcol); - else if (mcol) cp= (char *)mcol; - else glColor3ub(255, 255, 255); - - glTexCoord2f((tface->uv[0][0] - centerx) * sizex + transx, (tface->uv[0][1] - centery) * sizey + transy); - if (cp) glColor3ub(cp[3], cp[2], cp[1]); - glVertex3f(sizex * v1[0] + movex, sizey * v1[1] + movey, v1[2]); - - glTexCoord2f((tface->uv[1][0] - centerx) * sizex + transx, (tface->uv[1][1] - centery) * sizey + transy); - if (cp) glColor3ub(cp[7], cp[6], cp[5]); - glVertex3f(sizex * v2[0] + movex, sizey * v2[1] + movey, v2[2]); - - glTexCoord2f((tface->uv[2][0] - centerx) * sizex + transx, (tface->uv[2][1] - centery) * sizey + transy); - if (cp) glColor3ub(cp[11], cp[10], cp[9]); - glVertex3f(sizex * v3[0] + movex, sizey * v3[1] + movey, v3[2]); - - if(mf->v4) { - glTexCoord2f((tface->uv[3][0] - centerx) * sizex + transx, (tface->uv[3][1] - centery) * sizey + transy); - if (cp) glColor3ub(cp[15], cp[14], cp[13]); - glVertex3f(sizex * v4[0] + movex, sizey * v4[1] + movey, v4[2]); - } - - curpos+= advance; - } - glEnd(); - } - } - - ddm->release(ddm); - } + /* draw game engine text hack - but not if we are editing the mesh */ + if (get_property(ob, "Text") && me->mtface) { + if(ob==G.obedit) + editing= 1; + else if(ob==OBACT) + if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) + editing= 1; - /* switch off textures */ - set_tpage(0); + if(!editing) + draw_game_text_mesh(ob, me); } - glShadeModel(GL_FLAT); - glDisable(GL_CULL_FACE); + + draw_textured_end(); - if(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface) { + /* draw edges and selected faces over textured mesh */ + if(!G.obedit && faceselect) draw_tfaces3D(ob, me, dm); - } - - /* XXX, bad patch - default_gl_light() calls - * glLightfv(GL_LIGHT_POSITION, ...) which - * is transformed by the current matrix... we - * need to make sure that matrix is identity. - * - * It would be better if drawmesh.c kept track - * of and restored the light settings it changed. - * - zr - */ - glPushMatrix(); - glLoadIdentity(); - default_gl_light(); - glPopMatrix(); - - glFrontFace(GL_CCW); - if(dt > OB_SOLID && !(ob==OBACT && (G.f & G_FACESELECT) && me && me->mtface)) { - if(ob->flag & SELECT) { - BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); - } else { - BIF_ThemeColor(TH_WIRE); - } - dm->drawLooseEdges(dm); - } + /* reset from negative scale correction */ + glFrontFace(GL_CCW); dm->release(dm); } @@ -1196,6 +1230,5 @@ void init_realtime_GL(void) glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); - } diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 843502e4a07..d4697fceb2c 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -1836,16 +1836,21 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived EM_init_index_arrays(1, 1, 1); if(dt>OB_WIRE) { - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); + if(G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID) { + draw_mesh_textured(ob, finalDM, 0); + } + else { + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED); - glEnable(GL_LIGHTING); - glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); + glEnable(GL_LIGHTING); + glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); - finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL, 0); + finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0); - glFrontFace(GL_CCW); - glDisable(GL_LIGHTING); - + glFrontFace(GL_CCW); + glDisable(GL_LIGHTING); + } + // Setup for drawing wire over, disable zbuffer // write to show selected edge wires better BIF_ThemeColor(TH_WIRE); @@ -2020,12 +2025,22 @@ static void draw_mesh_fancy(Base *base, int dt, int flag) draw_wire = 1; } else if( (ob==OBACT && (G.f & (G_FACESELECT|G_TEXTUREPAINT))) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) { - + int faceselect= (ob==OBACT && (G.f & G_FACESELECT) && me->mtface); + if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) { draw_mesh_object_outline(ob, dm); } - draw_tface_mesh(ob, ob->data, dt); + draw_mesh_textured(ob, dm, faceselect); + + if(!faceselect) { + if(base->flag & SELECT) + BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); + else + BIF_ThemeColor(TH_WIRE); + + dm->drawLooseEdges(dm); + } } else if(dt==OB_SOLID ) { |