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:
Diffstat (limited to 'source/blender/blenkernel/intern/editderivedmesh.c')
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c296
1 files changed, 230 insertions, 66 deletions
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 840935c090b..96bdfe88722 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -55,10 +55,9 @@
#include "MEM_guardedalloc.h"
-#include "GPU_extensions.h"
#include "GPU_glew.h"
-
-extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
+#include "GPU_shader.h"
+#include "GPU_basic_shader.h"
static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4]);
@@ -238,31 +237,71 @@ static void emDM_calcLoopNormalsSpaceArray(
}
+/** \name Tangent Space Calculation
+ * \{ */
+
+/* Necessary complexity to handle looptri's as quads for correct tangents */
+#define USE_LOOPTRI_DETECT_QUADS
+
typedef struct {
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
- BMLoop *(*looptris)[3];
+ const BMLoop *(*looptris)[3];
int cd_loop_uv_offset; /* texture coordinates */
const float (*orco)[3];
float (*tangent)[4]; /* destination */
int numTessFaces;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ /* map from 'fake' face index to looptri,
+ * quads will point to the first looptri of the quad */
+ const int *face_as_quad_map;
+ int num_face_as_quad_map;
+#endif
+
} SGLSLEditMeshToTangent;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+/* seems weak but only used on quads */
+static const BMLoop *bm_loop_at_face_index(const BMFace *f, int vert_index)
+{
+ const BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ while (vert_index--) {
+ l = l->next;
+ }
+ return l;
+}
+#endif
+
/* interface */
#include "mikktspace.h"
static int emdm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
{
SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ return pMesh->num_face_as_quad_map;
+#else
return pMesh->numTessFaces;
+#endif
}
static int emdm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
{
- //SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
+ if (pMesh->face_as_quad_map) {
+ const BMLoop **lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ return 4;
+ }
+ }
+ return 3;
+#else
UNUSED_VARS(pContext, face_num);
return 3;
+#endif
}
static void emdm_ts_GetPosition(
@@ -271,8 +310,30 @@ static void emdm_ts_GetPosition(
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- BMLoop **lt = pMesh->looptris[face_num];
- const float *co = lt[vert_index]->v->co;
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+ const float *co;
+
+finally:
+ co = l->v->co;
copy_v3_v3(r_co, co);
}
@@ -282,14 +343,33 @@ static void emdm_ts_GetTextureCoordinate(
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- BMLoop **lt = pMesh->looptris[face_num];
+ const BMLoop **lt;
+ const BMLoop *l;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+finally:
if (pMesh->cd_loop_uv_offset != -1) {
- const float *uv = BM_ELEM_CD_GET_VOID_P(lt[vert_index], pMesh->cd_loop_uv_offset);
+ const float *uv = BM_ELEM_CD_GET_VOID_P(l, pMesh->cd_loop_uv_offset);
copy_v2_v2(r_uv, uv);
}
else {
- const float *orco = pMesh->orco[BM_elem_index_get(lt[vert_index]->v)];
+ const float *orco = pMesh->orco[BM_elem_index_get(l->v)];
map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
}
}
@@ -300,22 +380,40 @@ static void emdm_ts_GetNormal(
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- BMLoop **lt = pMesh->looptris[face_num];
- const bool smoothnormal = BM_elem_flag_test_bool(lt[0]->f, BM_ELEM_SMOOTH);
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+finally:
if (pMesh->precomputedLoopNormals) {
- copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(lt[vert_index])]);
+ copy_v3_v3(r_no, pMesh->precomputedLoopNormals[BM_elem_index_get(l)]);
}
- else if (!smoothnormal) {
+ else if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
if (pMesh->precomputedFaceNormals) {
- copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(lt[0]->f)]);
+ copy_v3_v3(r_no, pMesh->precomputedFaceNormals[BM_elem_index_get(l->f)]);
}
else {
- copy_v3_v3(r_no, lt[0]->f->no);
+ copy_v3_v3(r_no, l->f->no);
}
}
else {
- copy_v3_v3(r_no, lt[vert_index]->v->no);
+ copy_v3_v3(r_no, l->v->no);
}
}
@@ -325,8 +423,30 @@ static void emdm_ts_SetTSpace(
{
//assert(vert_index >= 0 && vert_index < 4);
SGLSLEditMeshToTangent *pMesh = pContext->m_pUserData;
- BMLoop **lt = pMesh->looptris[face_num];
- float *pRes = pMesh->tangent[BM_elem_index_get(lt[vert_index])];
+ const BMLoop **lt;
+ const BMLoop *l;
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (pMesh->face_as_quad_map) {
+ lt = pMesh->looptris[pMesh->face_as_quad_map[face_num]];
+ if (lt[0]->f->len == 4) {
+ l = bm_loop_at_face_index(lt[0]->f, vert_index);
+ goto finally;
+ }
+ /* fall through to regular triangle */
+ }
+ else {
+ lt = pMesh->looptris[face_num];
+ }
+#else
+ lt = pMesh->looptris[face_num];
+#endif
+ l = lt[vert_index];
+
+ float *pRes;
+
+finally:
+ pRes = pMesh->tangent[BM_elem_index_get(l)];
copy_v3_v3(pRes, fvTangent);
pRes[3] = fSign;
}
@@ -387,6 +507,31 @@ static void emDM_calcLoopTangents(DerivedMesh *dm)
DM_add_loop_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
tangent = DM_get_loop_data_layer(dm, CD_TANGENT);
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ int num_face_as_quad_map;
+ int *face_as_quad_map = NULL;
+
+ /* map faces to quads */
+ if (bmdm->em->tottri != bm->totface) {
+ /* over alloc, since we dont know how many ngon or quads we have */
+
+ /* map fake face index to looptri */
+ face_as_quad_map = MEM_mallocN(sizeof(int) * totface, __func__);
+ int i, j;
+ for (i = 0, j = 0; j < totface; i++, j++) {
+ face_as_quad_map[i] = j;
+ /* step over all quads */
+ if (em->looptris[j][0]->f->len == 4) {
+ j++; /* skips the nest looptri */
+ }
+ }
+ num_face_as_quad_map = i;
+ }
+ else {
+ num_face_as_quad_map = totface;
+ }
+#endif
+
/* new computation method */
{
SGLSLEditMeshToTangent mesh2tangent = {NULL};
@@ -395,12 +540,17 @@ static void emDM_calcLoopTangents(DerivedMesh *dm)
mesh2tangent.precomputedFaceNormals = fnors;
mesh2tangent.precomputedLoopNormals = tlnors;
- mesh2tangent.looptris = em->looptris;
+ mesh2tangent.looptris = (const BMLoop *(*)[3])em->looptris;
mesh2tangent.cd_loop_uv_offset = cd_loop_uv_offset;
mesh2tangent.orco = (const float (*)[3])orco;
mesh2tangent.tangent = tangent;
mesh2tangent.numTessFaces = totface;
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ mesh2tangent.face_as_quad_map = face_as_quad_map;
+ mesh2tangent.num_face_as_quad_map = num_face_as_quad_map;
+#endif
+
sContext.m_pUserData = &mesh2tangent;
sContext.m_pInterface = &sInterface;
sInterface.m_getNumFaces = emdm_ts_GetNumFaces;
@@ -412,9 +562,19 @@ static void emDM_calcLoopTangents(DerivedMesh *dm)
/* 0 if failed */
genTangSpaceDefault(&sContext);
+
+#ifdef USE_LOOPTRI_DETECT_QUADS
+ if (face_as_quad_map) {
+ MEM_freeN(face_as_quad_map);
+ }
+#undef USE_LOOPTRI_DETECT_QUADS
+#endif
}
}
+/** \} */
+
+
static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
{
/* do nothing */
@@ -729,11 +889,9 @@ static void emDM_drawMappedFaces(
BMFace *efa;
struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
const int tottri = bmdm->em->tottri;
- const int lasttri = tottri - 1; /* compare agasint this a lot */
DMDrawOption draw_option;
- int i, flush;
- const int skip_normals = !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
-
+ int i;
+ const int skip_normals = !(flag & DM_DRAW_NEED_NORMALS);
const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
unsigned char(*color_vert_array)[4] = em->derivedVertColor;
@@ -745,6 +903,7 @@ static void emDM_drawMappedFaces(
/* GL_ZERO is used to detect if drawing has started or not */
GLenum poly_prev = GL_ZERO;
GLenum shade_prev = GL_ZERO;
+ DMDrawOption draw_option_prev = DM_DRAW_OPTION_SKIP;
/* call again below is ok */
if (has_vcol_preview) {
@@ -755,7 +914,8 @@ static void emDM_drawMappedFaces(
}
if (has_vcol_preview || has_fcol_preview) {
flag |= DM_DRAW_ALWAYS_SMOOTH;
- glDisable(GL_LIGHTING); /* grr */
+ /* weak, this logic should really be moved higher up */
+ setMaterial = NULL;
}
if (bmdm->vertexCos) {
@@ -792,8 +952,22 @@ static void emDM_drawMappedFaces(
if (draw_option != DM_DRAW_OPTION_SKIP) {
const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
+ if (draw_option_prev != draw_option) {
+ if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
+ if (poly_prev != GL_ZERO) glEnd();
+ poly_prev = GL_ZERO; /* force glBegin */
+
+ GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ }
+ draw_option_prev = draw_option;
+ }
+
+
if (efa->mat_nr != prev_mat_nr) {
if (setMaterial) {
+ if (poly_prev != GL_ZERO) glEnd();
+ poly_prev = GL_ZERO; /* force glBegin */
+
setMaterial(efa->mat_nr + 1, NULL);
}
prev_mat_nr = efa->mat_nr;
@@ -804,8 +978,8 @@ static void emDM_drawMappedFaces(
if (poly_prev != GL_ZERO) glEnd();
poly_prev = GL_ZERO; /* force glBegin */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
+ GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
+ GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
}
if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
@@ -858,17 +1032,6 @@ static void emDM_drawMappedFaces(
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
}
}
-
- flush = (draw_option == DM_DRAW_OPTION_STIPPLE);
- if (!skip_normals && !flush && (i != lasttri))
- flush |= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
-
- if (flush) {
- glEnd();
- poly_prev = GL_ZERO; /* force glBegin */
-
- glDisable(GL_POLYGON_STIPPLE);
- }
}
}
}
@@ -891,8 +1054,21 @@ static void emDM_drawMappedFaces(
if (draw_option != DM_DRAW_OPTION_SKIP) {
const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
+ if (draw_option_prev != draw_option) {
+ if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
+ if (poly_prev != GL_ZERO) glEnd();
+ poly_prev = GL_ZERO; /* force glBegin */
+
+ GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
+ }
+ draw_option_prev = draw_option;
+ }
+
if (efa->mat_nr != prev_mat_nr) {
if (setMaterial) {
+ if (poly_prev != GL_ZERO) glEnd();
+ poly_prev = GL_ZERO; /* force glBegin */
+
setMaterial(efa->mat_nr + 1, NULL);
}
prev_mat_nr = efa->mat_nr;
@@ -903,8 +1079,8 @@ static void emDM_drawMappedFaces(
if (poly_prev != GL_ZERO) glEnd();
poly_prev = GL_ZERO; /* force glBegin */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
+ GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
+ GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
}
if (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
@@ -958,18 +1134,6 @@ static void emDM_drawMappedFaces(
glVertex3fv(ltri[2]->v->co);
}
}
-
- flush = (draw_option == DM_DRAW_OPTION_STIPPLE);
- if (!skip_normals && !flush && (i != lasttri)) {
- flush |= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
- }
-
- if (flush) {
- glEnd();
- poly_prev = GL_ZERO; /* force glBegin */
-
- glDisable(GL_POLYGON_STIPPLE);
- }
}
}
}
@@ -1226,7 +1390,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
if (attribs->orco.gl_texco)
glTexCoord3fv(orco);
else
- glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ glVertexAttrib3fv(attribs->orco.gl_index, orco);
}
for (i = 0; i < attribs->tottface; i++) {
const float *uv;
@@ -1242,18 +1406,18 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
if (attribs->tface[i].gl_texco)
glTexCoord2fv(uv);
else
- glVertexAttrib2fvARB(attribs->tface[i].gl_index, uv);
+ glVertexAttrib2fv(attribs->tface[i].gl_index, uv);
}
for (i = 0; i < attribs->totmcol; i++) {
GLubyte col[4];
if (attribs->mcol[i].em_offset != -1) {
const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
- copy_v4_v4_char((char *)col, &cp->r);
+ copy_v4_v4_uchar(col, &cp->r);
}
else {
col[0] = 0; col[1] = 0; col[2] = 0; col[3] = 0;
}
- glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col);
+ glVertexAttrib4ubv(attribs->mcol[i].gl_index, col);
}
if (attribs->tottang) {
const float *tang;
@@ -1263,7 +1427,7 @@ static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const B
else {
tang = zero;
}
- glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
+ glVertexAttrib4fv(attribs->tang.gl_index, tang);
}
}
@@ -2170,8 +2334,8 @@ static void statvis_calc_overhang(
rgb_float_to_uchar(r_face_colors[index], fcol);
}
else {
- unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
- copy_v4_v4_char((char *)r_face_colors[index], (const char *)fallback);
+ const unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
+ copy_v4_v4_uchar(r_face_colors[index], fallback);
}
}
}
@@ -2210,7 +2374,7 @@ static void statvis_calc_thickness(
struct BMLoop *(*looptris)[3] = em->looptris;
/* fallback */
- const char col_fallback[4] = {64, 64, 64, 255};
+ const unsigned char col_fallback[4] = {64, 64, 64, 255};
struct BMBVHTree *bmtree;
@@ -2305,7 +2469,7 @@ static void statvis_calc_thickness(
rgb_float_to_uchar(r_face_colors[i], fcol);
}
else {
- copy_v4_v4_char((char *)r_face_colors[i], (const char *)col_fallback);
+ copy_v4_v4_uchar(r_face_colors[i], col_fallback);
}
}
}
@@ -2357,7 +2521,7 @@ static void statvis_calc_intersect(
index = BM_elem_index_get(f_hit);
- copy_v3_v3_char((char *)r_face_colors[index], (const char *)col);
+ copy_v3_v3_uchar(r_face_colors[index], col);
}
}
MEM_freeN(overlap);
@@ -2382,7 +2546,7 @@ static void statvis_calc_distort(
const float minmax_irange = 1.0f / (max - min);
/* fallback */
- const char col_fallback[4] = {64, 64, 64, 255};
+ const unsigned char col_fallback[4] = {64, 64, 64, 255};
/* now convert into global space */
BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
@@ -2431,7 +2595,7 @@ static void statvis_calc_distort(
rgb_float_to_uchar(r_face_colors[index], fcol);
}
else {
- copy_v4_v4_char((char *)r_face_colors[index], (const char *)col_fallback);
+ copy_v4_v4_uchar(r_face_colors[index], col_fallback);
}
}
}
@@ -2453,7 +2617,7 @@ static void statvis_calc_sharp(
int i;
/* fallback */
- const char col_fallback[4] = {64, 64, 64, 255};
+ const unsigned char col_fallback[4] = {64, 64, 64, 255};
(void)vertexCos; /* TODO */
@@ -2481,7 +2645,7 @@ static void statvis_calc_sharp(
rgb_float_to_uchar(r_vert_colors[i], fcol);
}
else {
- copy_v4_v4_char((char *)r_vert_colors[i], (const char *)col_fallback);
+ copy_v4_v4_uchar(r_vert_colors[i], col_fallback);
}
}
}