diff options
Diffstat (limited to 'source/blender/blenkernel/intern/editderivedmesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 296 |
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); } } } |