Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2014-04-13 14:29:21 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-04-13 14:34:45 +0400
commit41b8f8873284dc9a2b0df2151b5d384a4ea212d9 (patch)
tree60f43347ea0bad4e297357666ec643ea5050f043 /source/blender
parent0b7f5813973c515b84cd7c18ef6d7d1e59374237 (diff)
Split Normals I (3/5): Add 3Dview shading support of split normals.
Mostly monkey coding in gpu ("modern" VBO drawing) and DM variants ("legacy" drawing) code... Reviewers: brecht Reviewed By: brecht CC: campbellbarton Differential Revision: https://developer.blender.org/D367
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c145
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c76
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c205
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c16
4 files changed, 360 insertions, 82 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 9af6220e4b2..176ef505a9a 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -537,16 +537,9 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
-#define PASSVERT(index) { \
- if (shademodel == GL_SMOOTH) { \
- short *no = mvert[index].no; \
- glNormal3sv(no); \
- } \
- glVertex3fv(mvert[index].co); \
-} (void)0
-
if (cddm->pbvh && cddm->pbvh_draw) {
if (dm->numTessFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
@@ -567,7 +560,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
new_matnr = mface->mat_nr + 1;
- new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
+ new_shademodel = (lnors || (mface->flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) {
glEnd();
@@ -579,7 +572,20 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
}
if (drawCurrentMat) {
- if (shademodel == GL_FLAT) {
+ if (lnors) {
+ glNormal3sv((const GLshort *)lnors[0][0]);
+ glVertex3fv(mvert[mface->v1].co);
+ glNormal3sv((const GLshort *)lnors[0][1]);
+ glVertex3fv(mvert[mface->v2].co);
+ glNormal3sv((const GLshort *)lnors[0][2]);
+ glVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ glNormal3sv((const GLshort *)lnors[0][3]);
+ glVertex3fv(mvert[mface->v4].co);
+ }
+ lnors++;
+ }
+ else if (shademodel == GL_FLAT) {
if (nors) {
glNormal3fv(nors);
}
@@ -594,13 +600,24 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
}
glNormal3fv(nor);
}
+ glVertex3fv(mvert[mface->v1].co);
+ glVertex3fv(mvert[mface->v2].co);
+ glVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ glVertex3fv(mvert[mface->v4].co);
+ }
}
-
- PASSVERT(mface->v1);
- PASSVERT(mface->v2);
- PASSVERT(mface->v3);
- if (mface->v4) {
- PASSVERT(mface->v4);
+ else { /* shademodel == GL_SMOOTH */
+ glNormal3sv(mvert[mface->v1].no);
+ glVertex3fv(mvert[mface->v1].co);
+ glNormal3sv(mvert[mface->v2].no);
+ glVertex3fv(mvert[mface->v2].co);
+ glNormal3sv(mvert[mface->v3].no);
+ glVertex3fv(mvert[mface->v3].co);
+ if (mface->v4) {
+ glNormal3sv(mvert[mface->v4].no);
+ glVertex3fv(mvert[mface->v4].co);
+ }
}
}
@@ -623,7 +640,6 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
GPU_buffer_unbind();
}
-#undef PASSVERT
glShadeModel(GL_FLAT);
}
@@ -637,6 +653,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
MVert *mv = cddm->mvert;
MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
MCol *mcol;
int i, orig;
@@ -722,7 +739,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
cp = (unsigned char *) &mcol[i * 4];
- if (!(mf->flag & ME_SMOOTH)) {
+ if (!(lnors || (mf->flag & ME_SMOOTH))) {
if (nors) {
glNormal3fv(nors);
}
@@ -742,28 +759,33 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if (tf) glTexCoord2fv(tf[i].uv[0]);
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
mvert = &mv[mf->v1];
- if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
+ if (lnors) glNormal3sv((const GLshort *)lnors[0][0]);
+ else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
glVertex3fv(mvert->co);
-
+
if (tf) glTexCoord2fv(tf[i].uv[1]);
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
mvert = &mv[mf->v2];
- if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
+ if (lnors) glNormal3sv((const GLshort *)lnors[0][1]);
+ else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
glVertex3fv(mvert->co);
if (tf) glTexCoord2fv(tf[i].uv[2]);
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
mvert = &mv[mf->v3];
- if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
+ if (lnors) glNormal3sv((const GLshort *)lnors[0][2]);
+ else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
glVertex3fv(mvert->co);
if (mf->v4) {
if (tf) glTexCoord2fv(tf[i].uv[3]);
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
mvert = &mv[mf->v4];
- if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
+ if (lnors) glNormal3sv((const GLshort *)lnors[0][3]);
+ else if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
glVertex3fv(mvert->co);
}
+ if (lnors) lnors++;
glEnd();
}
@@ -865,6 +887,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
MFace *mf = cddm->mface;
MCol *mcol;
float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int colType, useColors = flag & DM_DRAW_USE_COLORS;
int i, orig;
@@ -895,7 +918,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
for (i = 0; i < dm->numTessFaceData; i++, mf++) {
- int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
+ int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH);
DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
@@ -921,7 +944,24 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
glShadeModel(GL_SMOOTH);
glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
- if (!drawSmooth) {
+ if (lnors) {
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3sv((const GLshort *)lnors[0][0]);
+ glVertex3fv(mv[mf->v1].co);
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3sv((const GLshort *)lnors[0][1]);
+ glVertex3fv(mv[mf->v2].co);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3sv((const GLshort *)lnors[0][2]);
+ glVertex3fv(mv[mf->v3].co);
+ if (mf->v4) {
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3sv((const GLshort *)lnors[0][3]);
+ glVertex3fv(mv[mf->v4].co);
+ }
+ lnors++;
+ }
+ else if (!drawSmooth) {
if (nors) {
glNormal3fv(nors);
}
@@ -1062,7 +1102,8 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
}
-static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
+static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert,
+ short (*lnor)[3], int smoothnormal)
{
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int b;
@@ -1119,9 +1160,13 @@ static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int
}
/* vertex normal */
- if (smoothnormal)
+ if (lnor) {
+ glNormal3sv((const GLshort *)lnor);
+ }
+ else if (smoothnormal) {
glNormal3sv(mvert[index].no);
-
+ }
+
/* vertex coordinate */
glVertex3fv(mvert[index].co);
}
@@ -1138,6 +1183,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
MFace *mface = cddm->mface;
/* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, b, matnr, new_matnr;
bool do_draw;
int orig;
@@ -1176,7 +1222,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
glBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- const int smoothnormal = (mface->flag & ME_SMOOTH);
+ const int smoothnormal = lnors || (mface->flag & ME_SMOOTH);
+ short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
new_matnr = mface->mat_nr + 1;
if (new_matnr != matnr) {
@@ -1222,14 +1269,22 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
}
}
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
+ if (lnors) {
+ ln1 = &lnors[0][0];
+ ln2 = &lnors[0][1];
+ ln3 = &lnors[0][2];
+ ln4 = &lnors[0][3];
+ lnors++;
+ }
+
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
if (mface->v4)
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal);
else
- cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal);
}
glEnd();
}
@@ -1465,6 +1520,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
MVert *mvert = cddm->mvert;
MFace *mf = cddm->mface;
float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, matnr, new_matnr;
int orig;
@@ -1499,7 +1555,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
glBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mf++) {
- const int smoothnormal = (mf->flag & ME_SMOOTH);
+ const int smoothnormal = lnors || (mf->flag & ME_SMOOTH);
+ short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
/* material */
new_matnr = mf->mat_nr + 1;
@@ -1539,15 +1596,23 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
}
}
+ if (lnors) {
+ ln1 = &lnors[0][0];
+ ln2 = &lnors[0][1];
+ ln3 = &lnors[0][2];
+ ln4 = &lnors[0][3];
+ lnors++;
+ }
+
/* 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);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, ln1, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, ln2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal);
if (mf->v4)
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, ln4, smoothnormal);
else
- cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
+ cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal);
}
glEnd();
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 5862c5358c4..19a621ad8d4 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -434,6 +434,7 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
int i, flush;
const int skip_normals = !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
unsigned char(*color_vert_array)[4] = em->derivedVertColor;
unsigned char(*color_face_array)[4] = em->derivedFaceColor;
@@ -479,14 +480,14 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
polyNos = bmdm->polyNos;
}
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
for (i = 0; i < tottri; i++) {
BMLoop **ltri = looptris[i];
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
draw_option = (!setDrawOptions ?
DM_DRAW_OPTION_NORMAL :
@@ -539,13 +540,16 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
}
else {
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
}
}
@@ -564,14 +568,14 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
}
}
else {
- BM_mesh_elem_index_ensure(bm, BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE);
for (i = 0; i < tottri; i++) {
BMLoop **ltri = looptris[i];
int drawSmooth;
efa = ltri[0]->f;
- drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
draw_option = (!setDrawOptions ?
DM_DRAW_OPTION_NORMAL :
@@ -625,13 +629,16 @@ static void emDM_drawMappedFaces(DerivedMesh *dm,
}
else {
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glNormal3fv(ltri[0]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else glNormal3fv(ltri[0]->v->no);
glVertex3fv(ltri[0]->v->co);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glNormal3fv(ltri[1]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else glNormal3fv(ltri[1]->v->no);
glVertex3fv(ltri[1]->v->co);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glNormal3fv(ltri[2]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else glNormal3fv(ltri[2]->v->no);
glVertex3fv(ltri[2]->v->co);
}
}
@@ -687,6 +694,7 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
BMesh *bm = em->bm;
struct BMLoop *(*looptris)[3] = em->looptris;
BMFace *efa;
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
MLoopUV *luv[3], dummyluv = {{0}};
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
@@ -726,14 +734,14 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
vertexNos = bmdm->vertexNos;
polyNos = bmdm->polyNos;
- BM_mesh_elem_index_ensure(bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
+ int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
DMDrawOption draw_option;
efa = ltri[0]->f;
@@ -774,17 +782,20 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
else {
glTexCoord2fv(luv[0]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
glTexCoord2fv(luv[1]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
glTexCoord2fv(luv[2]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
}
glEnd();
@@ -792,14 +803,14 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
}
}
else {
- BM_mesh_elem_index_ensure(bm, BM_VERT);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_LOOP | BM_VERT : BM_VERT);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
MTexPoly *tp = (cd_poly_tex_offset != -1) ? BM_ELEM_CD_GET_VOID_P(ltri[0]->f, cd_poly_tex_offset) : NULL;
MTFace mtf = {{{0}}};
/*unsigned char *cp = NULL;*/ /*UNUSED*/
- int drawSmooth = BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
+ int drawSmooth = lnors || BM_elem_flag_test(ltri[0]->f, BM_ELEM_SMOOTH);
DMDrawOption draw_option;
efa = ltri[0]->f;
@@ -840,17 +851,20 @@ static void emDM_drawFacesTex_common(DerivedMesh *dm,
else {
glTexCoord2fv(luv[0]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
- glNormal3fv(ltri[0]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
+ else glNormal3fv(ltri[0]->v->no);
glVertex3fv(ltri[0]->v->co);
glTexCoord2fv(luv[1]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
- glNormal3fv(ltri[1]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
+ else glNormal3fv(ltri[1]->v->no);
glVertex3fv(ltri[1]->v->co);
glTexCoord2fv(luv[2]->uv);
if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
- glNormal3fv(ltri[2]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
+ else glNormal3fv(ltri[2]->v->no);
glVertex3fv(ltri[2]->v->co);
}
glEnd();
@@ -951,6 +965,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
const float (*vertexCos)[3] = bmdm->vertexCos;
const float (*vertexNos)[3];
const float (*polyNos)[3];
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
BMFace *efa;
DMVertexAttribs attribs;
@@ -971,7 +986,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
@@ -997,7 +1012,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
if (do_draw) {
/* draw face */
- drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
if (!drawSmooth) {
if (vertexCos) {
@@ -1020,14 +1035,16 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
for (fi = 0; fi < 3; fi++) {
const int j = BM_elem_index_get(ltri[fi]->v);
emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
- glNormal3fv(vertexNos[j]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else glNormal3fv(vertexNos[j]);
glVertex3fv(vertexCos[j]);
}
}
else {
for (fi = 0; fi < 3; fi++) {
emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
- glNormal3fv(ltri[fi]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else glNormal3fv(ltri[fi]->v->no);
glVertex3fv(ltri[fi]->v->co);
}
}
@@ -1057,6 +1074,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
const float (*vertexCos)[3] = bmdm->vertexCos;
const float (*vertexNos)[3];
const float (*polyNos)[3];
+ const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
BMFace *efa;
DMVertexAttribs attribs = {{{NULL}}};
GPUVertexAttribs gattribs;
@@ -1073,7 +1091,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
/* always use smooth shading even for flat faces, else vertex colors wont interpolate */
glShadeModel(GL_SMOOTH);
- BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+ BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
for (i = 0; i < em->tottri; i++) {
BMLoop **ltri = looptris[i];
@@ -1098,7 +1116,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
}
/* draw face */
- drawSmooth = BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
+ drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
if (!drawSmooth) {
if (vertexCos) {
@@ -1121,14 +1139,16 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
for (fi = 0; fi < 3; fi++) {
const int j = BM_elem_index_get(ltri[fi]->v);
emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
- glNormal3fv(vertexNos[j]);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else glNormal3fv(vertexNos[j]);
glVertex3fv(vertexCos[j]);
}
}
else {
for (fi = 0; fi < 3; fi++) {
emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi], fi);
- glNormal3fv(ltri[fi]->v->no);
+ if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
+ else glNormal3fv(ltri[fi]->v->no);
glVertex3fv(ltri[fi]->v->co);
}
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 0b2d772978d..6a3b060ce36 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1730,7 +1730,9 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int gridSize = ccgSubSurf_getGridSize(ss);
+ int gridFaces = gridSize - 1;
DMFlagMat *faceFlags = ccgdm->faceFlags;
int step = (fast) ? gridSize - 1 : 1;
int i, totface = ccgSubSurf_getNumFaces(ss);
@@ -1754,9 +1756,10 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f);
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int new_matnr, new_shademodel;
+ short (*ln)[4][3] = NULL;
if (faceFlags) {
- new_shademodel = (faceFlags[index].flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
+ new_shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT;
new_matnr = faceFlags[index].mat_nr;
}
else {
@@ -1764,6 +1767,11 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
new_matnr = 0;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
if (shademodel != new_shademodel || matnr != new_matnr) {
matnr = new_matnr;
shademodel = new_shademodel;
@@ -1782,8 +1790,31 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
for (S = 0; S < numVerts; S++) {
CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (shademodel == GL_SMOOTH) {
- for (y = 0; y < gridSize - 1; y += step) {
+ if (ln) {
+ /* Can't use quad strips here... */
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y += step) {
+ for (x = 0; x < gridFaces; x += step) {
+ float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
+ float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
+ float *d = CCG_grid_elem_co(&key, faceGridData, x, y + step);
+
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(d);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(c);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(b);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(a);
+ ln += step;
+ }
+ }
+ glEnd();
+ }
+ else if (shademodel == GL_SMOOTH) {
+ for (y = 0; y < gridFaces; y += step) {
glBegin(GL_QUAD_STRIP);
for (x = 0; x < gridSize; x += step) {
CCGElem *a = CCG_grid_elem(&key, faceGridData, x, y + 0);
@@ -1799,8 +1830,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)
}
else {
glBegin(GL_QUADS);
- for (y = 0; y < gridSize - 1; y += step) {
- for (x = 0; x < gridSize - 1; x += step) {
+ for (y = 0; y < gridFaces; y += step) {
+ for (x = 0; x < gridFaces; x += step) {
float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
float *b = CCG_grid_elem_co(&key, faceGridData, x + step, y + 0);
float *c = CCG_grid_elem_co(&key, faceGridData, x + step, y + step);
@@ -1894,6 +1925,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
int gridFaces = gridSize - 1;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, i, do_draw, numVerts, matnr, new_matnr, totface;
CCG_key_top_level(&key, ss);
@@ -1913,6 +1945,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
totface = ccgSubSurf_getNumFaces(ss);
for (a = 0, i = 0; i < totface; i++) {
CCGFace *f = ccgdm->faceMap[i].face;
+ short (*ln)[4][3] = NULL;
int S, x, y, drawSmooth;
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int origIndex = ccgDM_getFaceMapIndex(ss, f);
@@ -1920,7 +1953,7 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
numVerts = ccgSubSurf_getFaceNumVerts(f);
if (faceFlags) {
- drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
new_matnr = faceFlags[index].mat_nr + 1;
}
else {
@@ -1928,6 +1961,11 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
new_matnr = 1;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
if (new_matnr != matnr) {
do_draw = setMaterial(matnr = new_matnr, &gattribs);
if (do_draw)
@@ -1946,7 +1984,35 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm,
CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *vda, *vdb;
- if (drawSmooth) {
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *aco = CCG_grid_elem_co(&key, faceGridData, x, y);
+ float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y);
+ float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ PASSATTRIB(0, 1, 1);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(dco);
+ PASSATTRIB(1, 1, 2);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(cco);
+ PASSATTRIB(1, 0, 3);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(bco);
+ PASSATTRIB(0, 0, 0);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(aco);
+
+ ln++;
+ a++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
glBegin(GL_QUAD_STRIP);
for (x = 0; x < gridFaces; x++) {
@@ -2031,6 +2097,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
int gridFaces = gridSize - 1;
int edgeSize = ccgSubSurf_getEdgeSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, i, numVerts, matnr, new_matnr, totface;
CCG_key_top_level(&key, ss);
@@ -2049,6 +2116,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
totface = ccgSubSurf_getNumFaces(ss);
for (a = 0, i = 0; i < totface; i++) {
CCGFace *f = ccgdm->faceMap[i].face;
+ short (*ln)[4][3] = NULL;
int S, x, y, drawSmooth;
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int origIndex = ccgDM_getFaceMapIndex(ss, f);
@@ -2057,7 +2125,7 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
/* get flags */
if (faceFlags) {
- drawSmooth = (faceFlags[index].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[index].flag & ME_SMOOTH));
new_matnr = faceFlags[index].mat_nr + 1;
}
else {
@@ -2065,6 +2133,11 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
new_matnr = 1;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
/* material */
if (new_matnr != matnr) {
setMaterial(userData, matnr = new_matnr, &gattribs);
@@ -2083,7 +2156,35 @@ static void ccgDM_drawMappedFacesMat(DerivedMesh *dm,
CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *vda, *vdb;
- if (drawSmooth) {
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *aco = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *bco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *cco = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *dco = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ PASSATTRIB(0, 1, 1);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(dco);
+ PASSATTRIB(1, 1, 2);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(cco);
+ PASSATTRIB(1, 0, 3);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(bco);
+ PASSATTRIB(0, 0, 0);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(aco);
+
+ ln++;
+ a++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
glBegin(GL_QUAD_STRIP);
for (x = 0; x < gridFaces; x++) {
@@ -2160,6 +2261,7 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
CCGKey key;
MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
DMFlagMat *faceFlags = ccgdm->faceFlags;
DMDrawOption draw_option;
int i, totface, gridSize = ccgSubSurf_getGridSize(ss);
@@ -2183,10 +2285,11 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
unsigned char *cp = NULL;
+ short (*ln)[4][3] = NULL;
int mat_nr;
if (faceFlags) {
- drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
+ drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
mat_nr = faceFlags[origIndex].mat_nr;
}
else {
@@ -2201,6 +2304,10 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
else
draw_option = GPU_enable_material(mat_nr, NULL) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
if (draw_option == DM_DRAW_OPTION_SKIP) {
if (tf) tf += gridFaces * gridFaces * numVerts;
@@ -2219,7 +2326,44 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
CCGElem *a, *b;
- if (drawSmooth) {
+ if (ln) {
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *a_co = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *c_co = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *d_co = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ if (tf) glTexCoord2fv(tf->uv[1]);
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(d_co);
+
+ if (tf) glTexCoord2fv(tf->uv[2]);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(c_co);
+
+ if (tf) glTexCoord2fv(tf->uv[3]);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(b_co);
+
+ if (tf) glTexCoord2fv(tf->uv[0]);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(a_co);
+
+ if (tf) tf++;
+ if (cp) cp += 16;
+ ln++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
glShadeModel(GL_SMOOTH);
for (y = 0; y < gridFaces; y++) {
glBegin(GL_QUAD_STRIP);
@@ -2360,6 +2504,7 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
CCGSubSurf *ss = ccgdm->ss;
CCGKey key;
MCol *mcol = NULL;
+ short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int i, gridSize = ccgSubSurf_getGridSize(ss);
DMFlagMat *faceFlags = ccgdm->faceFlags;
int useColors = flag & DM_DRAW_USE_COLORS;
@@ -2383,11 +2528,12 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f);
int origIndex;
unsigned char *cp = NULL;
+ short (*ln)[4][3] = NULL;
origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
if (flag & DM_DRAW_ALWAYS_SMOOTH) drawSmooth = 1;
- else if (faceFlags) drawSmooth = (faceFlags[origIndex].flag & ME_SMOOTH);
+ else if (faceFlags) drawSmooth = (lnors || (faceFlags[origIndex].flag & ME_SMOOTH));
else drawSmooth = 1;
if (mcol) {
@@ -2395,6 +2541,11 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
mcol += gridFaces * gridFaces * numVerts * 4;
}
+ if (lnors) {
+ ln = lnors;
+ lnors += gridFaces * gridFaces * numVerts;
+ }
+
{
DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
@@ -2415,7 +2566,35 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm,
for (S = 0; S < numVerts; S++) {
CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
- if (drawSmooth) {
+ if (ln) {
+ glBegin(GL_QUADS);
+ for (y = 0; y < gridFaces; y++) {
+ for (x = 0; x < gridFaces; x++) {
+ float *a = CCG_grid_elem_co(&key, faceGridData, x, y + 0);
+ float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 0);
+ float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1);
+ float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1);
+
+ if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+ glNormal3sv(ln[0][1]);
+ glVertex3fv(d);
+ if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+ glNormal3sv(ln[0][2]);
+ glVertex3fv(c);
+ if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+ glNormal3sv(ln[0][3]);
+ glVertex3fv(b);
+ if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+ glNormal3sv(ln[0][0]);
+ glVertex3fv(a);
+
+ if (cp) cp += 16;
+ ln++;
+ }
+ }
+ glEnd();
+ }
+ else if (drawSmooth) {
for (y = 0; y < gridFaces; y++) {
CCGElem *a, *b;
glBegin(GL_QUAD_STRIP);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 177ffd071fd..e2588c251fb 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -737,6 +737,7 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i
float f_no[3];
float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MVert *mvert = dm->getVertArray(dm);
MFace *f = dm->getTessFaceArray(dm);
@@ -747,7 +748,20 @@ static void GPU_buffer_copy_normal(DerivedMesh *dm, float *varray, int *index, i
start = index[mat_orig_to_new[f->mat_nr]];
index[mat_orig_to_new[f->mat_nr]] += f->v4 ? 18 : 9;
- if (smoothnormal) {
+ if (tlnors) {
+ short (*tlnor)[3] = tlnors[i];
+ /* Copy loop normals */
+ normal_short_to_float_v3(&varray[start], tlnor[0]);
+ normal_short_to_float_v3(&varray[start + 3], tlnor[1]);
+ normal_short_to_float_v3(&varray[start + 6], tlnor[2]);
+
+ if (f->v4) {
+ normal_short_to_float_v3(&varray[start + 9], tlnor[2]);
+ normal_short_to_float_v3(&varray[start + 12], tlnor[3]);
+ normal_short_to_float_v3(&varray[start + 15], tlnor[0]);
+ }
+ }
+ else if (smoothnormal) {
/* copy vertex normal */
normal_short_to_float_v3(&varray[start], mvert[f->v1].no);
normal_short_to_float_v3(&varray[start + 3], mvert[f->v2].no);