Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/cdderivedmesh.c
| Show First 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) | ||||
| } | } | ||||
| /* always build pbvh from original mesh, and only use it for drawing if | /* always build pbvh from original mesh, and only use it for drawing if | ||||
| * this derivedmesh is just original mesh. it's the multires subsurf dm | * this derivedmesh is just original mesh. it's the multires subsurf dm | ||||
| * that this is actually for, to support a pbvh on a modified mesh */ | * that this is actually for, to support a pbvh on a modified mesh */ | ||||
| if (!cddm->pbvh && ob->type == OB_MESH) { | if (!cddm->pbvh && ob->type == OB_MESH) { | ||||
| Mesh *me = ob->data; | Mesh *me = ob->data; | ||||
| const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop); | |||||
| MLoopTri *looptri; | |||||
| bool deformed; | bool deformed; | ||||
| cddm->pbvh = BKE_pbvh_new(); | cddm->pbvh = BKE_pbvh_new(); | ||||
| cddm->pbvh_draw = can_pbvh_draw(ob, dm); | cddm->pbvh_draw = can_pbvh_draw(ob, dm); | ||||
| BKE_mesh_tessface_ensure(me); | looptri = MEM_mallocN(sizeof(*looptri) * looptris_num, __func__); | ||||
| BKE_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, | BKE_mesh_recalc_looptri( | ||||
| me->totface, me->totvert, &me->vdata); | me->mloop, me->mpoly, | ||||
| me->mvert, | |||||
| me->totloop, me->totpoly, | |||||
| looptri); | |||||
| BKE_pbvh_build_mesh( | |||||
| cddm->pbvh, | |||||
| me->mpoly, me->mloop, | |||||
| me->mvert, me->totvert, &me->vdata, | |||||
| looptri, looptris_num); | |||||
| pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); | pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color); | ||||
| deformed = check_sculpt_object_deformed(ob, true); | deformed = check_sculpt_object_deformed(ob, true); | ||||
| if (deformed && ob->derivedDeform) { | if (deformed && ob->derivedDeform) { | ||||
| DerivedMesh *deformdm = ob->derivedDeform; | DerivedMesh *deformdm = ob->derivedDeform; | ||||
| float (*vertCos)[3]; | float (*vertCos)[3]; | ||||
| Show All 12 Lines | |||||
| /* update vertex normals so that drawing smooth faces works during sculpt | /* update vertex normals so that drawing smooth faces works during sculpt | ||||
| * TODO: proper fix is to support the pbvh in all drawing modes */ | * TODO: proper fix is to support the pbvh in all drawing modes */ | ||||
| static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) | static void cdDM_update_normals_from_pbvh(DerivedMesh *dm) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| float (*face_nors)[3]; | float (*face_nors)[3]; | ||||
| if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData) | if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numPolyData) | ||||
| return; | return; | ||||
| face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); | face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL); | ||||
| BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors); | BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors); | ||||
| } | } | ||||
| static void cdDM_drawVerts(DerivedMesh *dm) | static void cdDM_drawVerts(DerivedMesh *dm) | ||||
| { | { | ||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| if (dm->drawObject->tot_triangle_point) | if (dm->drawObject->tot_triangle_point) | ||||
| glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); | glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point); | ||||
| else | else | ||||
| glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); | glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point); | ||||
| GPU_buffer_unbind(); | GPU_buffer_unbind(); | ||||
| } | } | ||||
| static void cdDM_drawUVEdges(DerivedMesh *dm) | static void cdDM_drawUVEdges(DerivedMesh *dm) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| MFace *mf = cddm->mface; | const MLoopTri *lt = dm->looptris.array; | ||||
| int i; | int i; | ||||
| if (mf) { | if (lt) { | ||||
| const MPoly *mpoly = cddm->mpoly; | |||||
| int prevstart = 0; | int prevstart = 0; | ||||
| bool prevdraw = true; | bool prevdraw = true; | ||||
| int curpos = 0; | int curpos = 0; | ||||
| GPU_uvedge_setup(dm); | GPU_uvedge_setup(dm); | ||||
| for (i = 0; i < dm->numTessFaceData; i++, mf++) { | for (i = 0; i < dm->looptris.num; i++, lt++) { | ||||
| const bool draw = (mf->flag & ME_HIDE) == 0; | const MPoly *mp = &mpoly[lt->poly]; | ||||
| const bool draw = (mp->flag & ME_HIDE) == 0; | |||||
| if (prevdraw != draw) { | if (prevdraw != draw) { | ||||
| if (prevdraw && (curpos != prevstart)) { | if (prevdraw && (curpos != prevstart)) { | ||||
| glDrawArrays(GL_LINES, prevstart, curpos - prevstart); | glDrawArrays(GL_LINES, prevstart, curpos - prevstart); | ||||
| } | } | ||||
| prevstart = curpos; | prevstart = curpos; | ||||
| } | } | ||||
| if (mf->v4) { | |||||
| curpos += 8; | |||||
| } | |||||
| else { | |||||
| curpos += 6; | curpos += 6; | ||||
| } | |||||
| prevdraw = draw; | prevdraw = draw; | ||||
| } | } | ||||
| if (prevdraw && (curpos != prevstart)) { | if (prevdraw && (curpos != prevstart)) { | ||||
| glDrawArrays(GL_LINES, prevstart, curpos - prevstart); | glDrawArrays(GL_LINES, prevstart, curpos - prevstart); | ||||
| } | } | ||||
| GPU_buffer_unbind(); | GPU_buffer_unbind(); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
| static void cdDM_drawFacesTex_common(DerivedMesh *dm, | static void cdDM_drawFacesTex_common(DerivedMesh *dm, | ||||
| DMSetDrawOptionsTex drawParams, | DMSetDrawOptionsTex drawParams, | ||||
| DMSetDrawOptionsMappedTex drawParamsMapped, | DMSetDrawOptionsMappedTex drawParamsMapped, | ||||
| DMCompareDrawOptions compareDrawOptions, | DMCompareDrawOptions compareDrawOptions, | ||||
| void *userData, DMDrawFlag uvflag) | void *userData, DMDrawFlag uvflag) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); | |||||
| MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); | MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); | ||||
| MCol *mcol; | const MPoly *mpoly = cddm->mpoly; | ||||
| MLoopCol *mloopcol; | |||||
| int i; | int i; | ||||
| int colType, startFace = 0; | int colType, startFace = 0; | ||||
| bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; | bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; | ||||
| int tottri; | int tottri; | ||||
| int next_actualFace; | int next_actualFace; | ||||
| /* double lookup */ | |||||
| const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); | |||||
| const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | ||||
| if (index_mf_to_mpoly == NULL) { | |||||
| index_mp_to_orig = NULL; | |||||
| } | |||||
| /* TODO: not entirely correct, but currently dynamic topology will | /* TODO: not entirely correct, but currently dynamic topology will | ||||
| * destroy UVs anyway, so textured display wouldn't work anyway | * destroy UVs anyway, so textured display wouldn't work anyway | ||||
| * | * | ||||
| * this will do more like solid view with lights set up for | * this will do more like solid view with lights set up for | ||||
| * textured view, but object itself will be displayed gray | * textured view, but object itself will be displayed gray | ||||
| * (the same as it'll display without UV maps in textured view) | * (the same as it'll display without UV maps in textured view) | ||||
| */ | */ | ||||
| if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | ||||
| if (BKE_pbvh_has_faces(cddm->pbvh)) { | if (BKE_pbvh_has_faces(cddm->pbvh)) { | ||||
| GPU_set_tpage(NULL, false, false); | GPU_set_tpage(NULL, false, false); | ||||
| BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false); | BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| colType = CD_TEXTURE_MCOL; | colType = CD_TEXTURE_MLOOPCOL; | ||||
| mcol = dm->getTessFaceDataArray(dm, colType); | mloopcol = dm->getLoopDataArray(dm, colType); | ||||
| if (!mcol) { | if (!mloopcol) { | ||||
| colType = CD_PREVIEW_MCOL; | colType = CD_PREVIEW_MCOL; | ||||
| mcol = dm->getTessFaceDataArray(dm, colType); | mloopcol = dm->getLoopDataArray(dm, colType); | ||||
| } | } | ||||
| if (!mcol) { | if (!mloopcol) { | ||||
| colType = CD_MCOL; | colType = CD_MLOOPCOL; | ||||
| mcol = dm->getTessFaceDataArray(dm, colType); | mloopcol = dm->getLoopDataArray(dm, colType); | ||||
| } | } | ||||
| cdDM_update_normals_from_pbvh(dm); | cdDM_update_normals_from_pbvh(dm); | ||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| GPU_normal_setup(dm); | GPU_normal_setup(dm); | ||||
| if (uvflag & DM_DRAW_USE_TEXPAINT_UV) | if (uvflag & DM_DRAW_USE_TEXPAINT_UV) | ||||
| GPU_texpaint_uv_setup(dm); | GPU_texpaint_uv_setup(dm); | ||||
| else | else | ||||
| GPU_uv_setup(dm); | GPU_uv_setup(dm); | ||||
| if (mcol) { | if (mloopcol) { | ||||
| GPU_color_setup(dm, colType); | GPU_color_setup(dm, colType); | ||||
| } | } | ||||
| tottri = dm->drawObject->tot_triangle_point / 3; | tottri = dm->drawObject->tot_triangle_point / 3; | ||||
| next_actualFace = dm->drawObject->triangle_to_mface[0]; | next_actualFace = dm->drawObject->triangle_to_mpoly[0]; | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| /* lastFlag = 0; */ /* UNUSED */ | /* lastFlag = 0; */ /* UNUSED */ | ||||
| for (i = 0; i < tottri; i++) { | for (i = 0; i < tottri; i++) { | ||||
| int actualFace = next_actualFace; | int actualFace = next_actualFace; | ||||
| DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| int flush = 0; | int flush = 0; | ||||
| if (i != tottri - 1) | if (i != tottri - 1) | ||||
| next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; | next_actualFace = dm->drawObject->triangle_to_mpoly[i + 1]; | ||||
| if (drawParams) { | if (drawParams) { | ||||
| MTexPoly *tp = NULL; | draw_option = drawParams(use_tface && mtexpoly ? &mtexpoly[actualFace] : NULL, (mloopcol != NULL), mpoly[actualFace].mat_nr); | ||||
| if (use_tface && mtexpoly && index_mf_to_mpoly) { | |||||
| int actualFace_poly = index_mf_to_mpoly[actualFace]; | |||||
| if (actualFace_poly != ORIGINDEX_NONE) { | |||||
| tp = &mtexpoly[actualFace_poly]; | |||||
| } | |||||
| } | |||||
| draw_option = drawParams(tp, (mcol != NULL), mf[actualFace].mat_nr); | |||||
| } | } | ||||
| else { | else { | ||||
| if (index_mf_to_mpoly) { | if (index_mp_to_orig) { | ||||
| const int orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); | const int orig = index_mp_to_orig[actualFace]; | ||||
| if (orig == ORIGINDEX_NONE) { | if (orig == ORIGINDEX_NONE) { | ||||
| /* XXX, this is not really correct | /* XXX, this is not really correct | ||||
| * it will draw the previous faces context for this one when we don't know its settings. | * it will draw the previous faces context for this one when we don't know its settings. | ||||
| * but better then skipping it altogether. - campbell */ | * but better then skipping it altogether. - campbell */ | ||||
| draw_option = DM_DRAW_OPTION_NORMAL; | draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| } | } | ||||
| else if (drawParamsMapped) { | else if (drawParamsMapped) { | ||||
| draw_option = drawParamsMapped(userData, orig, mf[actualFace].mat_nr); | draw_option = drawParamsMapped(userData, orig, mpoly[actualFace].mat_nr); | ||||
| } | } | ||||
| } | } | ||||
| else if (drawParamsMapped) { | else if (drawParamsMapped) { | ||||
| draw_option = drawParamsMapped(userData, actualFace, mf[actualFace].mat_nr); | draw_option = drawParamsMapped(userData, actualFace, mpoly[actualFace].mat_nr); | ||||
| } | } | ||||
| } | } | ||||
| /* flush buffer if current triangle isn't drawable or it's last triangle */ | /* flush buffer if current triangle isn't drawable or it's last triangle */ | ||||
| flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); | flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1); | ||||
| if (!flush && compareDrawOptions) { | if (!flush && compareDrawOptions) { | ||||
| /* also compare draw options and flush buffer if they're different | /* also compare draw options and flush buffer if they're different | ||||
| * need for face selection highlight in edit mode */ | * need for face selection highlight in edit mode */ | ||||
| flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | ||||
| } | } | ||||
| if (flush) { | if (flush) { | ||||
| int first = startFace * 3; | int first = startFace * 3; | ||||
| /* Add one to the length if we're drawing at the end of the array */ | /* Add one to the length if we're drawing at the end of the array */ | ||||
| int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; | int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; | ||||
| if (count) { | if (count) { | ||||
| if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) | if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL) | ||||
| GPU_color_switch(1); | GPU_color_switch(1); | ||||
| else | else | ||||
| GPU_color_switch(0); | GPU_color_switch(0); | ||||
| glDrawArrays(GL_TRIANGLES, first, count); | glDrawArrays(GL_TRIANGLES, first, count); | ||||
| } | } | ||||
| startFace = i + 1; | startFace = i + 1; | ||||
| Show All 15 Lines | |||||
| static void cdDM_drawMappedFaces(DerivedMesh *dm, | static void cdDM_drawMappedFaces(DerivedMesh *dm, | ||||
| DMSetDrawOptions setDrawOptions, | DMSetDrawOptions setDrawOptions, | ||||
| DMSetMaterial setMaterial, | DMSetMaterial setMaterial, | ||||
| DMCompareDrawOptions compareDrawOptions, | DMCompareDrawOptions compareDrawOptions, | ||||
| void *userData, DMDrawFlag flag) | void *userData, DMDrawFlag flag) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| MVert *mv = cddm->mvert; | const MVert *mvert = cddm->mvert; | ||||
| MFace *mf = cddm->mface; | const MPoly *mpoly = cddm->mpoly; | ||||
| MCol *mcol; | const MLoop *mloop = cddm->mloop; | ||||
| const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); | const MLoopTri *lt = dm->looptris.array; | ||||
| const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); | const MLoopCol *mloopcol = NULL; | ||||
| int colType, useColors = flag & DM_DRAW_USE_COLORS; | const float (*nors)[3] = DM_get_poly_data_layer(dm, CD_NORMAL); | ||||
| const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); | |||||
| int colType; | |||||
| int i, orig; | int i, orig; | ||||
| /* double lookup */ | |||||
| const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); | |||||
| const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | ||||
| if (index_mf_to_mpoly == NULL) { | |||||
| index_mp_to_orig = NULL; | |||||
| } | |||||
| colType = CD_TEXTURE_MCOL; | if (flag & DM_DRAW_USE_COLORS) { | ||||
| mcol = DM_get_tessface_data_layer(dm, colType); | colType = CD_TEXTURE_MLOOPCOL; | ||||
| if (!mcol) { | mloopcol = DM_get_loop_data_layer(dm, colType); | ||||
| colType = CD_PREVIEW_MCOL; | if (!mloopcol) { | ||||
| mcol = DM_get_tessface_data_layer(dm, colType); | colType = CD_PREVIEW_MLOOPCOL; | ||||
| mloopcol = DM_get_loop_data_layer(dm, colType); | |||||
| } | |||||
| if (!mloopcol) { | |||||
| colType = CD_MLOOPCOL; | |||||
| mloopcol = DM_get_loop_data_layer(dm, colType); | |||||
| } | } | ||||
| if (!mcol) { | |||||
| colType = CD_MCOL; | |||||
| mcol = DM_get_tessface_data_layer(dm, colType); | |||||
| } | } | ||||
| cdDM_update_normals_from_pbvh(dm); | cdDM_update_normals_from_pbvh(dm); | ||||
| /* back-buffer always uses legacy since VBO's would need the | /* back-buffer always uses legacy since VBO's would need the | ||||
| * color array temporarily overwritten for drawing, then reset. */ | * color array temporarily overwritten for drawing, then reset. */ | ||||
| if (G.f & G_BACKBUFSEL) { | if (G.f & G_BACKBUFSEL) { | ||||
| DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); | DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n"); | ||||
| for (i = 0; i < dm->numTessFaceData; i++, mf++) { | for (i = 0; i < dm->looptris.num; i++, lt++) { | ||||
| int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mf->flag & ME_SMOOTH); | const MPoly *mp = &mpoly[lt->poly]; | ||||
| int drawSmooth = ((flag & DM_DRAW_ALWAYS_SMOOTH) || lnors) ? 1 : (mp->flag & ME_SMOOTH); | |||||
| DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | 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; | orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly; | ||||
| if (orig == ORIGINDEX_NONE) | if (orig == ORIGINDEX_NONE) | ||||
| draw_option = setMaterial(mf->mat_nr + 1, NULL); | draw_option = setMaterial(mp->mat_nr + 1, NULL); | ||||
| else if (setDrawOptions != NULL) | else if (setDrawOptions != NULL) | ||||
| draw_option = setDrawOptions(userData, orig); | draw_option = setDrawOptions(userData, orig); | ||||
| if (draw_option != DM_DRAW_OPTION_SKIP) { | if (draw_option != DM_DRAW_OPTION_SKIP) { | ||||
| unsigned char *cp = NULL; | const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; | ||||
| const unsigned int *ltri = lt->tri; | |||||
| int j; | |||||
| if (draw_option == DM_DRAW_OPTION_STIPPLE) { | if (draw_option == DM_DRAW_OPTION_STIPPLE) { | ||||
| glEnable(GL_POLYGON_STIPPLE); | glEnable(GL_POLYGON_STIPPLE); | ||||
| glPolygonStipple(stipple_quarttone); | glPolygonStipple(stipple_quarttone); | ||||
| } | } | ||||
| if (useColors && mcol) | |||||
| cp = (unsigned char *)&mcol[i * 4]; | |||||
| /* no need to set shading mode to flat because | /* no need to set shading mode to flat because | ||||
| * normals are already used to change shading */ | * normals are already used to change shading */ | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES); | glBegin(GL_TRIANGLES); | ||||
| if (lnors) { | if (lnors) { | ||||
| if (cp) glColor3ub(cp[3], cp[2], cp[1]); | for (j = 0; j < 3; j++) { | ||||
| glNormal3sv((const GLshort *)lnors[0][0]); | if (mloopcol) glColor3ubv((unsigned char *)&mloopcol[ltri[j]].r); | ||||
| glVertex3fv(mv[mf->v1].co); | glNormal3fv(lnors[ltri[j]]); | ||||
| if (cp) glColor3ub(cp[7], cp[6], cp[5]); | glVertex3fv(mvert[vtri[j]].co); | ||||
| 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); | |||||
| } | } | ||||
| } | } | ||||
| else if (!drawSmooth) { | else if (!drawSmooth) { | ||||
| if (nors) { | if (nors) { | ||||
| glNormal3fv(nors); | glNormal3fv(nors[lt->poly]); | ||||
| } | } | ||||
| else { | else { | ||||
| float nor[3]; | float nor[3]; | ||||
| if (mf->v4) { | normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); | ||||
| normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); | |||||
| } | |||||
| else { | |||||
| normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); | |||||
| } | |||||
| glNormal3fv(nor); | glNormal3fv(nor); | ||||
| } | } | ||||
| if (cp) glColor3ub(cp[3], cp[2], cp[1]); | for (j = 0; j < 3; j++) { | ||||
| glVertex3fv(mv[mf->v1].co); | if (mloopcol) glColor3ubv((unsigned char *)&mloopcol[ltri[j]].r); | ||||
| if (cp) glColor3ub(cp[7], cp[6], cp[5]); | glVertex3fv(mvert[vtri[j]].co); | ||||
| glVertex3fv(mv[mf->v2].co); | |||||
| if (cp) glColor3ub(cp[11], cp[10], cp[9]); | |||||
| glVertex3fv(mv[mf->v3].co); | |||||
| if (mf->v4) { | |||||
| if (cp) glColor3ub(cp[15], cp[14], cp[13]); | |||||
| glVertex3fv(mv[mf->v4].co); | |||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (cp) glColor3ub(cp[3], cp[2], cp[1]); | for (j = 0; j < 3; j++) { | ||||
| glNormal3sv(mv[mf->v1].no); | if (mloopcol) glColor3ubv((unsigned char *)&mloopcol[ltri[j]].r); | ||||
| glVertex3fv(mv[mf->v1].co); | glNormal3sv(mvert[vtri[j]].no); | ||||
| if (cp) glColor3ub(cp[7], cp[6], cp[5]); | glVertex3fv(mvert[vtri[j]].co); | ||||
| glNormal3sv(mv[mf->v2].no); | |||||
| glVertex3fv(mv[mf->v2].co); | |||||
| if (cp) glColor3ub(cp[11], cp[10], cp[9]); | |||||
| glNormal3sv(mv[mf->v3].no); | |||||
| glVertex3fv(mv[mf->v3].co); | |||||
| if (mf->v4) { | |||||
| if (cp) glColor3ub(cp[15], cp[14], cp[13]); | |||||
| glNormal3sv(mv[mf->v4].no); | |||||
| glVertex3fv(mv[mf->v4].co); | |||||
| } | } | ||||
| } | } | ||||
| glEnd(); | glEnd(); | ||||
| if (draw_option == DM_DRAW_OPTION_STIPPLE) | if (draw_option == DM_DRAW_OPTION_STIPPLE) | ||||
| glDisable(GL_POLYGON_STIPPLE); | glDisable(GL_POLYGON_STIPPLE); | ||||
| } | } | ||||
| if (nors) | |||||
| nors += 3; | |||||
| if (lnors) | |||||
| lnors++; | |||||
| } | } | ||||
| } | } | ||||
| else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ | else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ | ||||
| int prevstart = 0; | int prevstart = 0; | ||||
| int tottri; | int tottri; | ||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| GPU_normal_setup(dm); | GPU_normal_setup(dm); | ||||
| if (useColors && mcol) { | if (mloopcol) { | ||||
| GPU_color_setup(dm, colType); | GPU_color_setup(dm, colType); | ||||
| } | } | ||||
| tottri = dm->drawObject->tot_triangle_point / 3; | tottri = dm->drawObject->tot_triangle_point / 3; | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| if (tottri == 0) { | if (tottri == 0) { | ||||
| /* avoid buffer problems in following code */ | /* avoid buffer problems in following code */ | ||||
| } | } | ||||
| else if (setDrawOptions == NULL) { | else if (setDrawOptions == NULL) { | ||||
| /* just draw the entire face array */ | /* just draw the entire face array */ | ||||
| glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); | glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3); | ||||
| } | } | ||||
| else { | else { | ||||
| /* we need to check if the next material changes */ | /* we need to check if the next material changes */ | ||||
| int next_actualFace = dm->drawObject->triangle_to_mface[0]; | int next_actualFace = dm->drawObject->triangle_to_mpoly[0]; | ||||
| short prev_mat_nr = -1; | short prev_mat_nr = -1; | ||||
| for (i = 0; i < tottri; i++) { | for (i = 0; i < tottri; i++) { | ||||
| //int actualFace = dm->drawObject->triangle_to_mface[i]; | //int actualFace = dm->drawObject->triangle_to_mpoly[i]; | ||||
| int actualFace = next_actualFace; | int actualFace = next_actualFace; | ||||
| MFace *mface = mf + actualFace; | const MPoly *mp = &mpoly[actualFace]; | ||||
| /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */ | /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mp->flag & ME_SMOOTH);*/ /* UNUSED */ | ||||
| DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| int flush = 0; | int flush = 0; | ||||
| if (i != tottri - 1) | if (i != tottri - 1) | ||||
| next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; | next_actualFace = dm->drawObject->triangle_to_mpoly[i + 1]; | ||||
| orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; | orig = (index_mp_to_orig) ? index_mp_to_orig[actualFace] : actualFace; | ||||
| if (mface->mat_nr != prev_mat_nr) { | if (mp->mat_nr != prev_mat_nr) { | ||||
| if (setMaterial) | if (setMaterial) | ||||
| draw_option = setMaterial(mface->mat_nr + 1, NULL); | draw_option = setMaterial(mp->mat_nr + 1, NULL); | ||||
| prev_mat_nr = mface->mat_nr; | prev_mat_nr = mp->mat_nr; | ||||
| } | } | ||||
| if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) | if (setDrawOptions != NULL && (orig != ORIGINDEX_NONE)) | ||||
| draw_option = setDrawOptions(userData, orig); | draw_option = setDrawOptions(userData, orig); | ||||
| if (draw_option == DM_DRAW_OPTION_STIPPLE) { | if (draw_option == DM_DRAW_OPTION_STIPPLE) { | ||||
| glEnable(GL_POLYGON_STIPPLE); | glEnable(GL_POLYGON_STIPPLE); | ||||
| glPolygonStipple(stipple_quarttone); | glPolygonStipple(stipple_quarttone); | ||||
| } | } | ||||
| /* Goal is to draw as long of a contiguous triangle | /* Goal is to draw as long of a contiguous triangle | ||||
| * array as possible, so draw when we hit either an | * array as possible, so draw when we hit either an | ||||
| * invisible triangle or at the end of the array */ | * invisible triangle or at the end of the array */ | ||||
| /* flush buffer if current triangle isn't drawable or it's last triangle... */ | /* flush buffer if current triangle isn't drawable or it's last triangle... */ | ||||
| flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); | flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == tottri - 1); | ||||
| /* ... or when material setting is dissferent */ | /* ... or when material setting is dissferent */ | ||||
| flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr; | flush |= mpoly[actualFace].mat_nr != mpoly[next_actualFace].mat_nr; | ||||
| if (!flush && compareDrawOptions) { | if (!flush && compareDrawOptions) { | ||||
| flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | ||||
| } | } | ||||
| if (flush) { | if (flush) { | ||||
| int first = prevstart * 3; | int first = prevstart * 3; | ||||
| /* Add one to the length if we're drawing at the end of the array */ | /* Add one to the length if we're drawing at the end of the array */ | ||||
| Show All 19 Lines | static void cdDM_drawMappedFacesTex(DerivedMesh *dm, | ||||
| DMSetDrawOptionsMappedTex setDrawOptions, | DMSetDrawOptionsMappedTex setDrawOptions, | ||||
| DMCompareDrawOptions compareDrawOptions, | DMCompareDrawOptions compareDrawOptions, | ||||
| void *userData, DMDrawFlag flag) | void *userData, DMDrawFlag flag) | ||||
| { | { | ||||
| cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag); | cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag); | ||||
| } | } | ||||
| static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int vert, | static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int vert, | ||||
| const short (*lnor)[3], const bool smoothnormal) | const float *lnor, const bool smoothnormal) | ||||
| { | { | ||||
| DM_draw_attrib_vertex(attribs, a, index, vert); | DM_draw_attrib_vertex(attribs, a, index, vert); | ||||
| /* vertex normal */ | /* vertex normal */ | ||||
| if (lnor) { | if (lnor) { | ||||
| glNormal3sv((const GLshort *)lnor); | glNormal3fv(lnor); | ||||
| } | } | ||||
| else if (smoothnormal) { | else if (smoothnormal) { | ||||
| glNormal3sv(mvert[index].no); | glNormal3sv(mvert[index].no); | ||||
| } | } | ||||
| /* vertex coordinate */ | /* vertex coordinate */ | ||||
| glVertex3fv(mvert[index].co); | glVertex3fv(mvert[index].co); | ||||
| } | } | ||||
| static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, | static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, | ||||
| DMSetMaterial setMaterial, | DMSetMaterial setMaterial, | ||||
| DMSetDrawOptions setDrawOptions, | DMSetDrawOptions setDrawOptions, | ||||
| void *userData) | void *userData) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| GPUVertexAttribs gattribs; | GPUVertexAttribs gattribs; | ||||
| DMVertexAttribs attribs; | DMVertexAttribs attribs; | ||||
| const MVert *mvert = cddm->mvert; | const MVert *mvert = cddm->mvert; | ||||
| const MFace *mface = cddm->mface; | const MPoly *mpoly = cddm->mpoly; | ||||
| const MLoop *mloop = cddm->mloop; | |||||
| const MLoopTri *lt = dm->looptris.array; | |||||
| /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ | /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ | ||||
| const float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); | const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); | ||||
| const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); | const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); | ||||
| int a, b, matnr, new_matnr; | int a, b, matnr, new_matnr; | ||||
| bool do_draw; | bool do_draw; | ||||
| int orig; | int orig; | ||||
| /* double lookup */ | |||||
| const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); | |||||
| const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | ||||
| if (index_mf_to_mpoly == NULL) { | |||||
| index_mp_to_orig = NULL; | |||||
| } | |||||
| /* TODO: same as for solid draw, not entirely correct, but works fine for now, | /* TODO: same as for solid draw, not entirely correct, but works fine for now, | ||||
| * will skip using textures (dyntopo currently destroys UV anyway) and | * will skip using textures (dyntopo currently destroys UV anyway) and | ||||
| * works fine for matcap | * works fine for matcap | ||||
| */ | */ | ||||
| if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | ||||
| if (BKE_pbvh_has_faces(cddm->pbvh)) { | if (BKE_pbvh_has_faces(cddm->pbvh)) { | ||||
| setMaterial(1, &gattribs); | setMaterial(1, &gattribs); | ||||
| Show All 12 Lines | static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, | ||||
| /* workaround for NVIDIA GPUs on Mac not supporting vertex arrays + interleaved formats, see T43342 */ | /* workaround for NVIDIA GPUs on Mac not supporting vertex arrays + interleaved formats, see T43342 */ | ||||
| if ((GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY) && (U.gameflags & USER_DISABLE_VBO)) || | if ((GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY) && (U.gameflags & USER_DISABLE_VBO)) || | ||||
| setDrawOptions != NULL) | setDrawOptions != NULL) | ||||
| { | { | ||||
| DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n"); | DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n"); | ||||
| memset(&attribs, 0, sizeof(attribs)); | memset(&attribs, 0, sizeof(attribs)); | ||||
| glBegin(GL_QUADS); | glBegin(GL_TRIANGLES); | ||||
| for (a = 0; a < dm->numTessFaceData; a++, mface++) { | for (a = 0; a < dm->looptris.num; a++, lt++) { | ||||
| const bool smoothnormal = lnors || (mface->flag & ME_SMOOTH); | const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; | ||||
| const short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; | const unsigned int *ltri = lt->tri; | ||||
| new_matnr = mface->mat_nr + 1; | const MPoly *mp = &mpoly[lt->poly]; | ||||
| const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH); | |||||
| const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL; | |||||
| new_matnr = mp->mat_nr + 1; | |||||
| if (new_matnr != matnr) { | if (new_matnr != matnr) { | ||||
| glEnd(); | glEnd(); | ||||
| do_draw = setMaterial(matnr = new_matnr, &gattribs); | do_draw = setMaterial(matnr = new_matnr, &gattribs); | ||||
| if (do_draw) | if (do_draw) | ||||
| DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); | DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); | ||||
| glBegin(GL_QUADS); | glBegin(GL_TRIANGLES); | ||||
| } | } | ||||
| if (!do_draw) { | if (!do_draw) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| else if (setDrawOptions) { | else if (setDrawOptions) { | ||||
| orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; | orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly; | ||||
| if (orig == ORIGINDEX_NONE) { | if (orig == ORIGINDEX_NONE) { | ||||
| /* since the material is set by setMaterial(), faces with no | /* since the material is set by setMaterial(), faces with no | ||||
| * origin can be assumed to be generated by a modifier */ | * origin can be assumed to be generated by a modifier */ | ||||
| /* continue */ | /* continue */ | ||||
| } | } | ||||
| else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP) | else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP) | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (!smoothnormal) { | if (!smoothnormal) { | ||||
| if (nors) { | if (nors) { | ||||
| glNormal3fv(nors[a]); | glNormal3fv(nors[a]); | ||||
| } | } | ||||
| else { | else { | ||||
| /* TODO ideally a normal layer should always be available */ | /* TODO ideally a normal layer should always be available */ | ||||
| float nor[3]; | float nor[3]; | ||||
| if (mface->v4) { | normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); | ||||
| normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co); | |||||
| } | |||||
| else { | |||||
| normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co); | |||||
| } | |||||
| glNormal3fv(nor); | glNormal3fv(nor); | ||||
| } | } | ||||
| } | } | ||||
| else if (lnors) { | else if (lnors) { | ||||
| ln1 = &lnors[a][0]; | ln1 = lnors[ltri[0]]; | ||||
| ln2 = &lnors[a][1]; | ln2 = lnors[ltri[1]]; | ||||
| ln3 = &lnors[a][2]; | ln3 = lnors[ltri[2]]; | ||||
| ln4 = &lnors[a][3]; | |||||
| } | } | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], 0, ln1, smoothnormal); | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, ln2, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], 1, ln2, smoothnormal); | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], 2, ln3, smoothnormal); | ||||
| if (mface->v4) | |||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, ln4, smoothnormal); | |||||
| else | |||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, ln3, smoothnormal); | |||||
| } | } | ||||
| glEnd(); | glEnd(); | ||||
| } | } | ||||
| else { | else { | ||||
| GPUBuffer *buffer = NULL; | GPUBuffer *buffer = NULL; | ||||
| char *varray = NULL; | char *varray = NULL; | ||||
| int numdata = 0, elementsize = 0, offset; | int numdata = 0, elementsize = 0, offset; | ||||
| int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; | int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; | ||||
| int i; | int i; | ||||
| const MFace *mf = mface; | const MPoly *mp; | ||||
| GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ | GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/ | ||||
| memset(&attribs, 0, sizeof(attribs)); | memset(&attribs, 0, sizeof(attribs)); | ||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| GPU_normal_setup(dm); | GPU_normal_setup(dm); | ||||
| for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { | for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { | ||||
| a = dm->drawObject->triangle_to_mface[i]; | a = dm->drawObject->triangle_to_mpoly[i]; | ||||
| mface = mf + a; | mp = &mpoly[a]; | ||||
| new_matnr = mface->mat_nr + 1; | new_matnr = mp->mat_nr + 1; | ||||
| if (new_matnr != matnr) { | if (new_matnr != matnr) { | ||||
| numfaces = curface - start; | numfaces = curface - start; | ||||
| if (numfaces > 0) { | if (numfaces > 0) { | ||||
| if (do_draw) { | if (do_draw) { | ||||
| if (numdata != 0) { | if (numdata != 0) { | ||||
| ▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) { | ||||
| * prevdraw was assumed true but didnt run so set to false - [#21036] */ | * prevdraw was assumed true but didnt run so set to false - [#21036] */ | ||||
| /* prevdraw = 0; */ /* UNUSED */ | /* prevdraw = 0; */ /* UNUSED */ | ||||
| buffer = NULL; | buffer = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (do_draw && numdata != 0) { | if (do_draw && numdata != 0) { | ||||
| const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; | |||||
| const unsigned int *ltri = lt->tri; | |||||
| offset = 0; | offset = 0; | ||||
| if (attribs.totorco && attribs.orco.array) { | if (attribs.totorco && attribs.orco.array) { | ||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]); | copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[vtri[0]]); | ||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]); | copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[vtri[1]]); | ||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]); | copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[vtri[2]]); | ||||
| offset += sizeof(float) * 3; | offset += sizeof(float) * 3; | ||||
| } | } | ||||
| for (b = 0; b < attribs.tottface; b++) { | for (b = 0; b < attribs.tottface; b++) { | ||||
| if (attribs.tface[b].array) { | if (attribs.tface[b].array) { | ||||
| MTFace *tf = &attribs.tface[b].array[a]; | const MLoopUV *mloopuv = attribs.tface[b].array; | ||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]); | copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], mloopuv[ltri[0]].uv); | ||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]); | copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], mloopuv[ltri[1]].uv); | ||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], mloopuv[ltri[2]].uv); | |||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]); | |||||
| offset += sizeof(float) * 2; | offset += sizeof(float) * 2; | ||||
| } | } | ||||
| } | } | ||||
| for (b = 0; b < attribs.totmcol; b++) { | for (b = 0; b < attribs.totmcol; b++) { | ||||
| if (attribs.mcol[b].array) { | if (attribs.mcol[b].array) { | ||||
| MCol *cp = &attribs.mcol[b].array[a * 4 + 0]; | const MLoopCol *mloopcol = attribs.mcol[b].array; | ||||
| GLubyte col[4]; | copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], &mloopcol[ltri[0]].r); | ||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], &mloopcol[ltri[1]].r); | ||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); | copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], &mloopcol[ltri[2]].r); | ||||
| cp = &attribs.mcol[b].array[a * 4 + 1]; | |||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | |||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); | |||||
| cp = &attribs.mcol[b].array[a * 4 + 2]; | |||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | |||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); | |||||
| offset += sizeof(unsigned char) * 4; | offset += sizeof(unsigned char) * 4; | ||||
| } | } | ||||
| } | } | ||||
| if (attribs.tottang && attribs.tang.array) { | if (attribs.tottang && attribs.tang.array) { | ||||
| const float *tang = attribs.tang.array[a * 4 + 0]; | const float *tang = attribs.tang.array[a * 4 + 0]; | ||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); | copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); | ||||
| tang = attribs.tang.array[a * 4 + 1]; | tang = attribs.tang.array[a * 4 + 1]; | ||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); | copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); | ||||
| tang = attribs.tang.array[a * 4 + 2]; | tang = attribs.tang.array[a * 4 + 2]; | ||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); | copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); | ||||
| offset += sizeof(float) * 4; | offset += sizeof(float) * 4; | ||||
| } | } | ||||
| (void)offset; | (void)offset; | ||||
| } | } | ||||
| curface++; | curface++; | ||||
| if (mface->v4) { | |||||
| if (do_draw && numdata != 0) { | |||||
| offset = 0; | |||||
| if (attribs.totorco && attribs.orco.array) { | |||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]); | |||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]); | |||||
| copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]); | |||||
| offset += sizeof(float) * 3; | |||||
| } | |||||
| for (b = 0; b < attribs.tottface; b++) { | |||||
| if (attribs.tface[b].array) { | |||||
| MTFace *tf = &attribs.tface[b].array[a]; | |||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]); | |||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]); | |||||
| copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]); | |||||
| offset += sizeof(float) * 2; | |||||
| } | |||||
| } | |||||
| for (b = 0; b < attribs.totmcol; b++) { | |||||
| if (attribs.mcol[b].array) { | |||||
| MCol *cp = &attribs.mcol[b].array[a * 4 + 2]; | |||||
| GLubyte col[4]; | |||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | |||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col); | |||||
| cp = &attribs.mcol[b].array[a * 4 + 3]; | |||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | |||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col); | |||||
| cp = &attribs.mcol[b].array[a * 4 + 0]; | |||||
| col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a; | |||||
| copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col); | |||||
| offset += sizeof(unsigned char) * 4; | |||||
| } | |||||
| } | |||||
| if (attribs.tottang && attribs.tang.array) { | |||||
| const float *tang = attribs.tang.array[a * 4 + 2]; | |||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang); | |||||
| tang = attribs.tang.array[a * 4 + 3]; | |||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang); | |||||
| tang = attribs.tang.array[a * 4 + 0]; | |||||
| copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang); | |||||
| offset += sizeof(float) * 4; | |||||
| } | |||||
| (void)offset; | |||||
| } | |||||
| curface++; | |||||
| i++; | |||||
| } | |||||
| } | } | ||||
| numfaces = curface - start; | numfaces = curface - start; | ||||
| if (numfaces > 0) { | if (numfaces > 0) { | ||||
| if (do_draw) { | if (do_draw) { | ||||
| if (numdata != 0) { | if (numdata != 0) { | ||||
| GPU_buffer_unlock(buffer); | GPU_buffer_unlock(buffer); | ||||
| GPU_interleaved_attrib_setup(buffer, datatypes, numdata); | GPU_interleaved_attrib_setup(buffer, datatypes, numdata); | ||||
| } | } | ||||
| Show All 16 Lines | |||||
| static void cdDM_drawMappedFacesMat(DerivedMesh *dm, | static void cdDM_drawMappedFacesMat(DerivedMesh *dm, | ||||
| void (*setMaterial)(void *userData, int matnr, void *attribs), | void (*setMaterial)(void *userData, int matnr, void *attribs), | ||||
| bool (*setFace)(void *userData, int index), void *userData) | bool (*setFace)(void *userData, int index), void *userData) | ||||
| { | { | ||||
| CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | CDDerivedMesh *cddm = (CDDerivedMesh *) dm; | ||||
| GPUVertexAttribs gattribs; | GPUVertexAttribs gattribs; | ||||
| DMVertexAttribs attribs; | DMVertexAttribs attribs; | ||||
| MVert *mvert = cddm->mvert; | MVert *mvert = cddm->mvert; | ||||
| MFace *mf = cddm->mface; | const MPoly *mpoly = cddm->mpoly; | ||||
| const float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); | const MLoop *mloop = cddm->mloop; | ||||
| const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); | const MLoopTri *lt = dm->looptris.array; | ||||
| const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); | |||||
| const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); | |||||
| int a, matnr, new_matnr; | int a, matnr, new_matnr; | ||||
| int orig; | int orig; | ||||
| /* double lookup */ | |||||
| const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); | |||||
| const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); | ||||
| if (index_mf_to_mpoly == NULL) { | |||||
| index_mp_to_orig = NULL; | |||||
| } | |||||
| /* TODO: same as for solid draw, not entirely correct, but works fine for now, | /* TODO: same as for solid draw, not entirely correct, but works fine for now, | ||||
| * will skip using textures (dyntopo currently destroys UV anyway) and | * will skip using textures (dyntopo currently destroys UV anyway) and | ||||
| * works fine for matcap | * works fine for matcap | ||||
| */ | */ | ||||
| if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | if (cddm->pbvh && cddm->pbvh_draw && BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH) { | ||||
| if (BKE_pbvh_has_faces(cddm->pbvh)) { | if (BKE_pbvh_has_faces(cddm->pbvh)) { | ||||
| setMaterial(userData, 1, &gattribs); | setMaterial(userData, 1, &gattribs); | ||||
| BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false); | BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false); | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| cdDM_update_normals_from_pbvh(dm); | cdDM_update_normals_from_pbvh(dm); | ||||
| matnr = -1; | matnr = -1; | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| memset(&attribs, 0, sizeof(attribs)); | memset(&attribs, 0, sizeof(attribs)); | ||||
| glBegin(GL_QUADS); | glBegin(GL_TRIANGLES); | ||||
| for (a = 0; a < dm->numTessFaceData; a++, mf++) { | for (a = 0; a < dm->looptris.num; a++, lt++) { | ||||
| const bool smoothnormal = lnors || (mf->flag & ME_SMOOTH); | const MPoly *mp = &mpoly[lt->poly]; | ||||
| const short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL; | const unsigned int vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v}; | ||||
| const unsigned int *ltri = lt->tri; | |||||
| const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH); | |||||
| const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL; | |||||
| /* material */ | /* material */ | ||||
| new_matnr = mf->mat_nr + 1; | new_matnr = mp->mat_nr + 1; | ||||
| if (new_matnr != matnr) { | if (new_matnr != matnr) { | ||||
| glEnd(); | glEnd(); | ||||
| setMaterial(userData, matnr = new_matnr, &gattribs); | setMaterial(userData, matnr = new_matnr, &gattribs); | ||||
| DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); | DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); | ||||
| glBegin(GL_QUADS); | glBegin(GL_TRIANGLES); | ||||
| } | } | ||||
| /* skipping faces */ | /* skipping faces */ | ||||
| if (setFace) { | if (setFace) { | ||||
| orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; | orig = (index_mp_to_orig) ? index_mp_to_orig[a] : lt->poly; | ||||
| if (orig != ORIGINDEX_NONE && !setFace(userData, orig)) | if (orig != ORIGINDEX_NONE && !setFace(userData, orig)) | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* smooth normal */ | /* smooth normal */ | ||||
| if (!smoothnormal) { | if (!smoothnormal) { | ||||
| if (nors) { | if (nors) { | ||||
| glNormal3fv(nors[a]); | glNormal3fv(nors[a]); | ||||
| } | } | ||||
| else { | else { | ||||
| /* TODO ideally a normal layer should always be available */ | /* TODO ideally a normal layer should always be available */ | ||||
| float nor[3]; | float nor[3]; | ||||
| normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); | |||||
| if (mf->v4) | |||||
| normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); | |||||
| else | |||||
| normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); | |||||
| glNormal3fv(nor); | glNormal3fv(nor); | ||||
| } | } | ||||
| } | } | ||||
| else if (lnors) { | else if (lnors) { | ||||
| ln1 = &lnors[a][0]; | ln1 = lnors[ltri[0]]; | ||||
| ln2 = &lnors[a][1]; | ln2 = lnors[ltri[1]]; | ||||
| ln3 = &lnors[a][2]; | ln3 = lnors[ltri[2]]; | ||||
| ln4 = &lnors[a][3]; | |||||
| } | } | ||||
| /* vertices */ | /* vertices */ | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, ln1, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], 0, ln1, smoothnormal); | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, ln2, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], 1, ln2, smoothnormal); | ||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); | cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], 2, ln3, smoothnormal); | ||||
| if (mf->v4) | |||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, ln4, smoothnormal); | |||||
| else | |||||
| cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, ln3, smoothnormal); | |||||
| } | } | ||||
| glEnd(); | glEnd(); | ||||
| glShadeModel(GL_FLAT); | glShadeModel(GL_FLAT); | ||||
| } | } | ||||
| static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData) | static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const bool do_face_nor_cpy) | ||||
| CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData); | CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData); | ||||
| } | } | ||||
| void CDDM_recalc_tessellation(DerivedMesh *dm) | void CDDM_recalc_tessellation(DerivedMesh *dm) | ||||
| { | { | ||||
| CDDM_recalc_tessellation_ex(dm, true); | CDDM_recalc_tessellation_ex(dm, true); | ||||
| } | } | ||||
| void CDDM_recalc_looptri(DerivedMesh *dm) | |||||
| { | |||||
| CDDerivedMesh *cddm = (CDDerivedMesh *)dm; | |||||
| const unsigned int totpoly = dm->numPolyData; | |||||
| const unsigned int totloop = dm->numLoopData; | |||||
| DM_ensure_looptri_data(dm); | |||||
| BKE_mesh_recalc_looptri( | |||||
| cddm->mloop, cddm->mpoly, | |||||
| cddm->mvert, | |||||
| totloop, totpoly, | |||||
| cddm->dm.looptris.array); | |||||
| } | |||||
| static void cdDM_free_internal(CDDerivedMesh *cddm) | static void cdDM_free_internal(CDDerivedMesh *cddm) | ||||
| { | { | ||||
| if (cddm->pmap) MEM_freeN(cddm->pmap); | if (cddm->pmap) MEM_freeN(cddm->pmap); | ||||
| if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem); | if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem); | ||||
| } | } | ||||
| static void cdDM_release(DerivedMesh *dm) | static void cdDM_release(DerivedMesh *dm) | ||||
| { | { | ||||
| Show All 38 Lines | static CDDerivedMesh *cdDM_create(const char *desc) | ||||
| dm->getVertDataArray = DM_get_vert_data_layer; | dm->getVertDataArray = DM_get_vert_data_layer; | ||||
| dm->getEdgeDataArray = DM_get_edge_data_layer; | dm->getEdgeDataArray = DM_get_edge_data_layer; | ||||
| dm->getTessFaceDataArray = DM_get_tessface_data_layer; | dm->getTessFaceDataArray = DM_get_tessface_data_layer; | ||||
| dm->calcNormals = CDDM_calc_normals; | dm->calcNormals = CDDM_calc_normals; | ||||
| dm->calcLoopNormals = CDDM_calc_loop_normals; | dm->calcLoopNormals = CDDM_calc_loop_normals; | ||||
| dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr; | dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr; | ||||
| dm->recalcTessellation = CDDM_recalc_tessellation; | dm->recalcTessellation = CDDM_recalc_tessellation; | ||||
| dm->recalcLooptri = CDDM_recalc_looptri; | |||||
| dm->getVertCos = cdDM_getVertCos; | dm->getVertCos = cdDM_getVertCos; | ||||
| dm->getVertCo = cdDM_getVertCo; | dm->getVertCo = cdDM_getVertCo; | ||||
| dm->getVertNo = cdDM_getVertNo; | dm->getVertNo = cdDM_getVertNo; | ||||
| dm->getPBVH = cdDM_getPBVH; | dm->getPBVH = cdDM_getPBVH; | ||||
| dm->getPolyMap = cdDM_getPolyMap; | dm->getPolyMap = cdDM_getPolyMap; | ||||
| ▲ Show 20 Lines • Show All 537 Lines • ▼ Show 20 Lines | if (dm->numTessFaceData == 0) { | ||||
| CDDM_recalc_tessellation_ex(dm, false); | CDDM_recalc_tessellation_ex(dm, false); | ||||
| } | } | ||||
| else { | else { | ||||
| /* A tessellation already exists, it should always have a CD_ORIGINDEX */ | /* A tessellation already exists, it should always have a CD_ORIGINDEX */ | ||||
| BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); | BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); | ||||
| CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData); | CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData); | ||||
| } | } | ||||
| face_nors = MEM_mallocN(sizeof(*face_nors) * dm->numTessFaceData, "face_nors"); | face_nors = MEM_mallocN(sizeof(*face_nors) * dm->numPolyData, "face_nors"); | ||||
| /* calculate face normals */ | /* calculate face normals */ | ||||
| BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), | BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), | ||||
| dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData, | dm->numLoopData, dm->numPolyData, face_nors, | ||||
| CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors, | |||||
| only_face_normals); | only_face_normals); | ||||
| CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numTessFaceData); | CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numPolyData); | ||||
| cddm->dm.dirty &= ~DM_DIRTY_NORMALS; | cddm->dm.dirty &= ~DM_DIRTY_NORMALS; | ||||
| } | } | ||||
| void CDDM_calc_normals_mapping(DerivedMesh *dm) | void CDDM_calc_normals_mapping(DerivedMesh *dm) | ||||
| { | { | ||||
| /* use this to skip calculating normals on original vert's, this may need to be changed */ | /* use this to skip calculating normals on original vert's, this may need to be changed */ | ||||
| const bool only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT); | const bool only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT); | ||||
| ▲ Show 20 Lines • Show All 995 Lines • Show Last 20 Lines | |||||