Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/cdderivedmesh.c
| Show First 20 Lines • Show All 288 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_loop_verts) | if (dm->drawObject->tot_loop_verts) | ||||
| glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loop_verts); | glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loop_verts); | ||||
| 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 83 Lines • ▼ Show 20 Lines | |||||
| static void cdDM_drawFacesTex_common( | static void cdDM_drawFacesTex_common( | ||||
| DerivedMesh *dm, | 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); | const MPoly *mpoly = cddm->mpoly; | ||||
| const MLoopTri *looptri = dm->looptris.array; | |||||
| const MLoopCol *mloopcol; | |||||
| MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); | MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY); | ||||
| MCol *mcol; | MCol *mcol; | ||||
| int i, orig; | int i; | ||||
| int colType, start_element, tot_drawn; | int colType, start_element, tot_drawn; | ||||
| bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; | bool use_tface = (uvflag & DM_DRAW_USE_ACTIVE_UV) != 0; | ||||
| int totpoly; | int totpoly; | ||||
| int next_actualFace; | int next_actualFace; | ||||
| int mat_index; | int mat_index; | ||||
| int tot_element; | int tot_element; | ||||
| /* double lookup */ | /* 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, false); | BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, 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); | ||||
| GPU_triangle_setup(dm); | GPU_triangle_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 (mcol) { | ||||
| GPU_color_setup(dm, colType); | GPU_color_setup(dm, colType); | ||||
| } | } | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| /* lastFlag = 0; */ /* UNUSED */ | /* lastFlag = 0; */ /* UNUSED */ | ||||
| for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { | for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { | ||||
| GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; | GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; | ||||
| next_actualFace = bufmat->polys[0]; | next_actualFace = looptri[bufmat->polys[0]].poly; | ||||
| totpoly = bufmat->totpolys; | totpoly = bufmat->totpolys; | ||||
| tot_element = 0; | tot_element = 0; | ||||
| tot_drawn = 0; | tot_drawn = 0; | ||||
| start_element = 0; | start_element = 0; | ||||
| for (i = 0; i < totpoly; i++) { | for (i = 0; i < totpoly; i++) { | ||||
| int actualFace = bufmat->polys[i]; | int actualFace = looptri[bufmat->polys[i]].poly; | ||||
| DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| int flush = 0; | int flush = 0; | ||||
| if (i != totpoly - 1) | if (i != totpoly - 1) | ||||
| next_actualFace = bufmat->polys[i + 1]; | next_actualFace = looptri[bufmat->polys[i + 1]].poly; | ||||
| if (drawParams) { | if (drawParams) { | ||||
| MTexPoly *tp = NULL; | draw_option = drawParams(use_tface && mtexpoly ? &mtexpoly[actualFace] : NULL, (mcol != 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) { | ||||
| 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 == totpoly - 1); | flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 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; | ||||
| } | } | ||||
| tot_element += mf[actualFace].v4 ? 6 : 3; | tot_element += 3; | ||||
| if (flush) { | if (flush) { | ||||
| if (draw_option != DM_DRAW_OPTION_SKIP) | if (draw_option != DM_DRAW_OPTION_SKIP) | ||||
| tot_drawn += mf[actualFace].v4 ? 6 : 3; | tot_drawn += 3; | ||||
| if (tot_drawn) { | if (tot_drawn) { | ||||
| if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) | if (mcol && 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); | ||||
| GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); | GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); | ||||
| tot_drawn = 0; | tot_drawn = 0; | ||||
| } | } | ||||
| start_element = tot_element; | start_element = tot_element; | ||||
| } | } | ||||
| else { | else { | ||||
| tot_drawn += mf[actualFace].v4 ? 6 : 3; | tot_drawn += 3; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GPU_buffer_unbind(); | GPU_buffer_unbind(); | ||||
| glShadeModel(GL_FLAT); | glShadeModel(GL_FLAT); | ||||
| } | } | ||||
| Show All 10 Lines | |||||
| static void cdDM_drawMappedFaces( | static void cdDM_drawMappedFaces( | ||||
| DerivedMesh *dm, | 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); | ||||
| int i, orig; | const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); | ||||
| int colType; | |||||
| int i; | |||||
| /* 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; | ||||
| int orig; | |||||
| 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]); | |||||
| glNormal3sv((const GLshort *)lnors[0][0]); | 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]); | glNormal3fv(lnors[ltri[j]]); | ||||
| glNormal3sv((const GLshort *)lnors[0][1]); | glVertex3fv(mvert[vtri[j]].co); | ||||
| 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 */ | ||||
| const MLoopTri *looptri = dm->looptris.array; | |||||
| int start_element = 0, tot_element, tot_drawn; | int start_element = 0, tot_element, tot_drawn; | ||||
| int totpoly; | int totpoly; | ||||
| int tottri; | int tottri; | ||||
| int mat_index; | int mat_index; | ||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| GPU_normal_setup(dm); | GPU_normal_setup(dm); | ||||
| GPU_triangle_setup(dm); | GPU_triangle_setup(dm); | ||||
| if (useColors && mcol) { | if (mloopcol) { | ||||
| GPU_color_setup(dm, colType); | GPU_color_setup(dm, colType); | ||||
| } | } | ||||
| glShadeModel(GL_SMOOTH); | glShadeModel(GL_SMOOTH); | ||||
| tottri = dm->drawObject->tot_triangle_point; | tottri = dm->drawObject->tot_triangle_point; | ||||
| 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 */ | ||||
| GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri); | GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tottri); | ||||
| } | } | ||||
| else { | else { | ||||
| for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { | for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) { | ||||
| GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; | GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index; | ||||
| DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| int next_actualFace = bufmat->polys[0]; | int next_actualFace = looptri[bufmat->polys[0]].poly; | ||||
| totpoly = bufmat->totpolys; | totpoly = bufmat->totpolys; | ||||
| tot_element = 0; | tot_element = 0; | ||||
| tot_drawn = 0; | tot_drawn = 0; | ||||
| start_element = 0; | start_element = 0; | ||||
| if (setMaterial) | if (setMaterial) | ||||
| draw_option = setMaterial(bufmat->mat_nr + 1, NULL); | draw_option = setMaterial(bufmat->mat_nr + 1, NULL); | ||||
| if (draw_option != DM_DRAW_OPTION_SKIP) { | if (draw_option != DM_DRAW_OPTION_SKIP) { | ||||
| for (i = 0; i < totpoly; i++) { | for (i = 0; i < totpoly; i++) { | ||||
| //int actualFace = dm->drawObject->triangle_to_mface[i]; | |||||
| int actualFace = next_actualFace; | int actualFace = next_actualFace; | ||||
| int flush = 0; | int flush = 0; | ||||
| int orig; | |||||
| orig = index_mp_to_orig ? index_mp_to_orig[actualFace] : actualFace; | |||||
| draw_option = DM_DRAW_OPTION_NORMAL; | draw_option = DM_DRAW_OPTION_NORMAL; | ||||
| if (i != totpoly - 1) | if (i != totpoly - 1) | ||||
| next_actualFace = bufmat->polys[i + 1]; | next_actualFace = looptri[bufmat->polys[i + 1]].poly; | ||||
| orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; | |||||
| 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 == totpoly - 1); | flush = (ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) || (i == totpoly - 1); | ||||
| if (!flush && compareDrawOptions) { | if (!flush && compareDrawOptions) { | ||||
| flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0; | ||||
| } | } | ||||
| tot_element += mf[actualFace].v4 ? 6 : 3; | tot_element += 3; | ||||
| if (flush) { | if (flush) { | ||||
| if (!ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) | if (!ELEM(draw_option, DM_DRAW_OPTION_SKIP, DM_DRAW_OPTION_STIPPLE)) | ||||
| tot_drawn += mf[actualFace].v4 ? 6 : 3; | tot_drawn += 3; | ||||
| if (tot_drawn) { | if (tot_drawn) { | ||||
| GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); | GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn); | ||||
| tot_drawn = 0; | tot_drawn = 0; | ||||
| } | } | ||||
| start_element = tot_element; | start_element = tot_element; | ||||
| if (draw_option == DM_DRAW_OPTION_STIPPLE) | if (draw_option == DM_DRAW_OPTION_STIPPLE) | ||||
| glDisable(GL_POLYGON_STIPPLE); | glDisable(GL_POLYGON_STIPPLE); | ||||
| } | } | ||||
| else { | else { | ||||
| tot_drawn += mf[actualFace].v4 ? 6 : 3; | tot_drawn += 3; | ||||
| } | } | ||||
| } | } | ||||
| glShadeModel(GL_FLAT); | glShadeModel(GL_FLAT); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| GPU_buffer_unbind(); | GPU_buffer_unbind(); | ||||
| } | } | ||||
| } | } | ||||
| static void cdDM_drawMappedFacesTex( | static void cdDM_drawMappedFacesTex( | ||||
| DerivedMesh *dm, | 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( | ||||
| const short (*lnor)[3], const bool smoothnormal) | DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int loop, int vert, | ||||
| const float *lnor, const bool smoothnormal) | |||||
| { | { | ||||
| DM_draw_attrib_vertex(attribs, a, index, vert); | DM_draw_attrib_vertex(attribs, a, index, vert, loop); | ||||
| /* 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); | ||||
| } | } | ||||
| Show All 9 Lines | static void cdDM_drawMappedFacesGLSL( | ||||
| DerivedMesh *dm, | 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; | ||||
| 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 13 Lines | static void cdDM_drawMappedFacesGLSL( | ||||
| /* 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) | ||||
| { | { | ||||
| DMVertexAttribs attribs; | DMVertexAttribs attribs; | ||||
| 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 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}; | ||||
| new_matnr = mface->mat_nr; | const unsigned int *ltri = lt->tri; | ||||
| const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL; | |||||
| const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH); | |||||
| new_matnr = mp->mat_nr; | |||||
| 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_QUADS); | ||||
| } | } | ||||
| 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], ltri[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], ltri[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], ltri[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 { | ||||
| GPUMaterialConv *matconv; | GPUMaterialConv *matconv; | ||||
| int offset; | int offset; | ||||
| int totface = dm->getNumTessFaces(dm); | |||||
| int *mat_orig_to_new; | int *mat_orig_to_new; | ||||
| int tot_active_mat; | int tot_active_mat; | ||||
| GPUBuffer *buffer = NULL; | GPUBuffer *buffer = NULL; | ||||
| char *varray; | char *varray; | ||||
| int max_element_size = 0; | int max_element_size = 0; | ||||
| int tot_loops = 0; | int tot_loops = 0; | ||||
| const MFace *mf = mface; | |||||
| GPU_vertex_setup(dm); | GPU_vertex_setup(dm); | ||||
| GPU_normal_setup(dm); | GPU_normal_setup(dm); | ||||
| GPU_triangle_setup(dm); | GPU_triangle_setup(dm); | ||||
| tot_active_mat = dm->drawObject->totmaterial; | tot_active_mat = dm->drawObject->totmaterial; | ||||
| matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat, | matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat, | ||||
| "cdDM_drawMappedFacesGLSL.matconv"); | "cdDM_drawMappedFacesGLSL.matconv"); | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | for (a = 0; a < tot_active_mat; a++) { | ||||
| matconv[a].numdata = numdata; | matconv[a].numdata = numdata; | ||||
| max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size); | max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* part two, generate and fill the arrays with the data */ | /* part two, generate and fill the arrays with the data */ | ||||
| if (max_element_size > 0) { | if (max_element_size > 0) { | ||||
| const MLoopTri *lt = dm->looptris.array; | |||||
| buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts, false); | buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts, false); | ||||
| if (buffer == NULL) { | if (buffer == NULL) { | ||||
| buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts, true); | buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts, true); | ||||
| } | } | ||||
| varray = GPU_buffer_lock_stream(buffer); | varray = GPU_buffer_lock_stream(buffer); | ||||
| if (varray == NULL) { | if (varray == NULL) { | ||||
| GPU_buffer_unbind(); | GPU_buffer_unbind(); | ||||
| GPU_buffer_free(buffer); | GPU_buffer_free(buffer); | ||||
| MEM_freeN(mat_orig_to_new); | MEM_freeN(mat_orig_to_new); | ||||
| MEM_freeN(matconv); | MEM_freeN(matconv); | ||||
| fprintf(stderr, "Out of memory, can't draw object\n"); | fprintf(stderr, "Out of memory, can't draw object\n"); | ||||
| return; | return; | ||||
| } | } | ||||
| mface = mf; | for (a = 0; a < dm->looptris.num; a++, lt++) { | ||||
| const MPoly *mp = &mpoly[lt->poly]; | |||||
| for (a = 0; a < totface; a++, mface++) { | int i = mat_orig_to_new[mp->mat_nr]; | ||||
| int i = mat_orig_to_new[mface->mat_nr]; | |||||
| offset = tot_loops * max_element_size; | offset = tot_loops * max_element_size; | ||||
| if (matconv[i].numdata != 0) { | if (matconv[i].numdata != 0) { | ||||
| const unsigned int *ltri = lt->tri; | |||||
| const unsigned int vtri[3] = {mloop[ltri[0]].v, mloop[ltri[1]].v, mloop[ltri[2]].v}; | |||||
| if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) { | if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) { | ||||
| copy_v3_v3((float *)&varray[offset], (float *)matconv[i].attribs.orco.array[mface->v1]); | copy_v3_v3((float *)&varray[offset], (float *)matconv[i].attribs.orco.array[vtri[0]]); | ||||
| copy_v3_v3((float *)&varray[offset + max_element_size], (float *)matconv[i].attribs.orco.array[mface->v2]); | copy_v3_v3((float *)&varray[offset + max_element_size], (float *)matconv[i].attribs.orco.array[vtri[1]]); | ||||
| copy_v3_v3((float *)&varray[offset + max_element_size * 2], (float *)matconv[i].attribs.orco.array[mface->v3]); | copy_v3_v3((float *)&varray[offset + max_element_size * 2], (float *)matconv[i].attribs.orco.array[vtri[2]]); | ||||
| if (mface->v4) { | |||||
| copy_v3_v3((float *)&varray[offset + max_element_size * 3], (float *)matconv[i].attribs.orco.array[mface->v4]); | |||||
| } | |||||
| offset += sizeof(float) * 3; | offset += sizeof(float) * 3; | ||||
| } | } | ||||
| for (b = 0; b < matconv[i].attribs.tottface; b++) { | for (b = 0; b < matconv[i].attribs.tottface; b++) { | ||||
| if (matconv[i].attribs.tface[b].array) { | if (matconv[i].attribs.tface[b].array) { | ||||
| MTFace *tf = &matconv[i].attribs.tface[b].array[a]; | const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array; | ||||
| copy_v2_v2((float *)&varray[offset], tf->uv[0]); | copy_v2_v2((float *)&varray[offset], mloopuv[ltri[0]].uv); | ||||
| copy_v2_v2((float *)&varray[offset + max_element_size], tf->uv[1]); | copy_v2_v2((float *)&varray[offset + max_element_size], mloopuv[ltri[1]].uv); | ||||
| copy_v2_v2((float *)&varray[offset + max_element_size * 2], tf->uv[2]); | copy_v2_v2((float *)&varray[offset + max_element_size * 2], mloopuv[ltri[2]].uv); | ||||
| if (mface->v4) { | |||||
| copy_v2_v2((float *)&varray[offset + max_element_size * 3], tf->uv[3]); | |||||
| } | |||||
| offset += sizeof(float) * 2; | offset += sizeof(float) * 2; | ||||
| } | } | ||||
| } | } | ||||
| for (b = 0; b < matconv[i].attribs.totmcol; b++) { | for (b = 0; b < matconv[i].attribs.totmcol; b++) { | ||||
| if (matconv[i].attribs.mcol[b].array) { | if (matconv[i].attribs.mcol[b].array) { | ||||
| MCol *cp = &matconv[i].attribs.mcol[b].array[a * 4 + 0]; | const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array; | ||||
| GLubyte col[4]; | copy_v4_v4_char((char *)&varray[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[offset + max_element_size], &mloopcol[ltri[1]].r); | ||||
| copy_v4_v4_char((char *)&varray[offset], (char *)col); | copy_v4_v4_char((char *)&varray[offset + max_element_size * 2], &mloopcol[ltri[2]].r); | ||||
| cp = &matconv[i].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[offset + max_element_size], (char *)col); | |||||
| cp = &matconv[i].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[offset + max_element_size * 2], (char *)col); | |||||
| if (mface->v4) { | |||||
| cp = &matconv[i].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[offset + max_element_size * 3], (char *)col); | |||||
| } | |||||
| offset += sizeof(unsigned char) * 4; | offset += sizeof(unsigned char) * 4; | ||||
| } | } | ||||
| } | } | ||||
| if (matconv[i].attribs.tottang && matconv[i].attribs.tang.array) { | if (matconv[i].attribs.tottang && matconv[i].attribs.tang.array) { | ||||
| const float *tang = matconv[i].attribs.tang.array[a * 4 + 0]; | const float *tang = matconv[i].attribs.tang.array[i * 4 + 0]; | ||||
| copy_v4_v4((float *)&varray[offset], tang); | copy_v4_v4((float *)&varray[offset], tang); | ||||
| tang = matconv[i].attribs.tang.array[a * 4 + 1]; | tang = matconv[i].attribs.tang.array[i * 4 + 1]; | ||||
| copy_v4_v4((float *)&varray[offset + max_element_size], tang); | copy_v4_v4((float *)&varray[offset + max_element_size], tang); | ||||
| tang = matconv[i].attribs.tang.array[a * 4 + 2]; | tang = matconv[i].attribs.tang.array[i * 4 + 2]; | ||||
| copy_v4_v4((float *)&varray[offset + max_element_size * 2], tang); | copy_v4_v4((float *)&varray[offset + max_element_size * 2], tang); | ||||
| if (mface->v4) { | |||||
| tang = matconv[i].attribs.tang.array[a * 4 + 3]; | |||||
| copy_v4_v4((float *)&varray[offset + max_element_size * 3], tang); | |||||
| } | |||||
| offset += sizeof(float) * 4; | offset += sizeof(float) * 4; | ||||
| } | } | ||||
| } | } | ||||
| if (mface->v4) { | |||||
| tot_loops += 4; | |||||
| } | |||||
| else { | |||||
| tot_loops += 3; | tot_loops += 3; | ||||
| } | } | ||||
| } | |||||
| GPU_buffer_unlock(buffer); | GPU_buffer_unlock(buffer); | ||||
| } | } | ||||
| for (a = 0; a < tot_active_mat; a++) { | for (a = 0; a < tot_active_mat; a++) { | ||||
| new_matnr = dm->drawObject->materials[a].mat_nr; | new_matnr = dm->drawObject->materials[a].mat_nr; | ||||
| do_draw = setMaterial(new_matnr + 1, &gattribs); | do_draw = setMaterial(new_matnr + 1, &gattribs); | ||||
| Show All 29 Lines | static void cdDM_drawMappedFacesMat( | ||||
| DerivedMesh *dm, | 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, false); | BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, 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], ltri[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], ltri[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], ltri[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 All 19 Lines | static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData) | ||||
| glEnd(); | glEnd(); | ||||
| } | } | ||||
| static void cdDM_buffer_copy_triangles( | static void cdDM_buffer_copy_triangles( | ||||
| DerivedMesh *dm, unsigned int *varray, | DerivedMesh *dm, unsigned int *varray, | ||||
| const int *mat_orig_to_new) | const int *mat_orig_to_new) | ||||
| { | { | ||||
| GPUBufferMaterial *gpumat; | GPUBufferMaterial *gpumat; | ||||
| MFace *f; | int i, tottri, findex = 0; | ||||
| int i, start, totface, findex = 0; | |||||
| const MPoly *mpoly; | |||||
| const MLoopTri *lt; | |||||
| f = dm->getTessFaceArray(dm); | mpoly = dm->getPolyArray(dm); | ||||
| lt = dm->looptris.array; | |||||
| tottri = dm->looptris.num; | |||||
| totface = dm->getNumTessFaces(dm); | for (i = 0; i < tottri; i++, lt++) { | ||||
| for (i = 0; i < totface; i++, f++) { | int start; | ||||
| gpumat = dm->drawObject->materials + mat_orig_to_new[f->mat_nr]; | gpumat = dm->drawObject->materials + mat_orig_to_new[mpoly[lt->poly].mat_nr]; | ||||
| start = gpumat->counter; | start = gpumat->counter; | ||||
| /* v1 v2 v3 */ | /* v1 v2 v3 */ | ||||
| varray[start++] = findex; | varray[start++] = findex; | ||||
| varray[start++] = findex + 1; | varray[start++] = findex + 1; | ||||
| varray[start++] = findex + 2; | varray[start++] = findex + 2; | ||||
| if (f->v4) { | |||||
| /* v3 v4 v1 */ | |||||
| varray[start++] = findex + 2; | |||||
| varray[start++] = findex + 3; | |||||
| varray[start++] = findex; | |||||
| gpumat->counter += 6; | |||||
| findex += 4; | |||||
| } | |||||
| else { | |||||
| gpumat->counter += 3; | gpumat->counter += 3; | ||||
| findex += 3; | findex += 3; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| static void cdDM_buffer_copy_vertex( | static void cdDM_buffer_copy_vertex( | ||||
| DerivedMesh *dm, float *varray) | DerivedMesh *dm, float *varray) | ||||
| { | { | ||||
| MVert *mvert; | const MVert *mvert; | ||||
| MFace *f; | int i, j, start, tottri; | ||||
| int i, j, start, totface; | |||||
| const MLoop *mloop; | |||||
| const MLoopTri *lt; | |||||
| mloop = dm->getLoopArray(dm); | |||||
| mvert = dm->getVertArray(dm); | mvert = dm->getVertArray(dm); | ||||
| f = dm->getTessFaceArray(dm); | lt = dm->looptris.array; | ||||
| tottri = dm->looptris.num; | |||||
| start = 0; | start = 0; | ||||
| totface = dm->getNumTessFaces(dm); | |||||
| for (i = 0; i < totface; i++, f++) { | |||||
| /* v1 v2 v3 */ | |||||
| copy_v3_v3(&varray[start], mvert[f->v1].co); | |||||
| copy_v3_v3(&varray[start + 3], mvert[f->v2].co); | |||||
| copy_v3_v3(&varray[start + 6], mvert[f->v3].co); | |||||
| start += 9; | |||||
| if (f->v4) { | for (i = 0; i < tottri; i++, lt++) { | ||||
| /* v4 */ | copy_v3_v3(&varray[start + 0], mvert[mloop[lt->tri[0]].v].co); | ||||
| copy_v3_v3(&varray[start], mvert[f->v4].co); | copy_v3_v3(&varray[start + 3], mvert[mloop[lt->tri[1]].v].co); | ||||
| start += 3; | copy_v3_v3(&varray[start + 6], mvert[mloop[lt->tri[2]].v].co); | ||||
| } | start += 9; | ||||
| } | } | ||||
| /* copy loose points */ | /* copy loose points */ | ||||
| j = dm->drawObject->tot_triangle_point * 3; | j = dm->drawObject->tot_triangle_point * 3; | ||||
| for (i = 0; i < dm->drawObject->totvert; i++) { | for (i = 0; i < dm->drawObject->totvert; i++) { | ||||
| if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_triangle_point) { | if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_triangle_point) { | ||||
| copy_v3_v3(&varray[j], mvert[i].co); | copy_v3_v3(&varray[j], mvert[i].co); | ||||
| j += 3; | j += 3; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void cdDM_buffer_copy_normal( | static void cdDM_buffer_copy_normal( | ||||
| DerivedMesh *dm, short *varray) | DerivedMesh *dm, short *varray) | ||||
| { | { | ||||
| int i, totface; | int i, tottri; | ||||
| int start; | int start; | ||||
| const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); | const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL); | ||||
| const short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); | const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL); | ||||
| MVert *mvert = dm->getVertArray(dm); | const MVert *mvert = dm->getVertArray(dm); | ||||
| MFace *f = dm->getTessFaceArray(dm); | |||||
| const MPoly *mpoly; | |||||
| const MLoop *mloop; | |||||
| const MLoopTri *lt; | |||||
| mpoly = dm->getPolyArray(dm); | |||||
| mloop = dm->getLoopArray(dm); | |||||
| mvert = dm->getVertArray(dm); | |||||
| lt = dm->looptris.array; | |||||
| tottri = dm->looptris.num; | |||||
| totface = dm->getNumTessFaces(dm); | |||||
| start = 0; | start = 0; | ||||
| for (i = 0; i < totface; i++, f++) { | for (i = 0; i < tottri; i++, lt++) { | ||||
| const int smoothnormal = (f->flag & ME_SMOOTH); | const MPoly *mp = &mpoly[lt->poly]; | ||||
| const unsigned int *ltri = lt->tri; | |||||
| const bool smoothnormal = (mp->flag & ME_SMOOTH) != 0; | |||||
| if (tlnors) { | if (lnors) { | ||||
| const short (*ln)[3] = tlnors[i]; | |||||
| /* Copy loop normals */ | /* Copy loop normals */ | ||||
| copy_v3_v3_short(&varray[start], ln[0]); | normal_float_to_short_v3(&varray[start + 0], lnors[ltri[0]]); | ||||
| copy_v3_v3_short(&varray[start + 4], ln[1]); | normal_float_to_short_v3(&varray[start + 4], lnors[ltri[1]]); | ||||
| copy_v3_v3_short(&varray[start + 8], ln[2]); | normal_float_to_short_v3(&varray[start + 8], lnors[ltri[2]]); | ||||
| start += 12; | |||||
| if (f->v4) { | |||||
| copy_v3_v3_short(&varray[start], ln[3]); | |||||
| start += 4; | |||||
| } | |||||
| } | } | ||||
| else if (smoothnormal) { | else if (smoothnormal) { | ||||
| /* copy vertex normal */ | /* copy vertex normal */ | ||||
| copy_v3_v3_short(&varray[start], mvert[f->v1].no); | copy_v3_v3_short(&varray[start + 0], mvert[mloop[ltri[0]].v].no); | ||||
| copy_v3_v3_short(&varray[start + 4], mvert[f->v2].no); | copy_v3_v3_short(&varray[start + 4], mvert[mloop[ltri[1]].v].no); | ||||
| copy_v3_v3_short(&varray[start + 8], mvert[f->v3].no); | copy_v3_v3_short(&varray[start + 8], mvert[mloop[ltri[2]].v].no); | ||||
| start += 12; | |||||
| if (f->v4) { | |||||
| copy_v3_v3_short(&varray[start], mvert[f->v4].no); | |||||
| start += 4; | |||||
| } | |||||
| } | } | ||||
| else if (nors) { | else if (nors) { | ||||
| /* copy cached face normal */ | /* copy cached face normal */ | ||||
| short f_no_s[3]; | short f_no_s[3]; | ||||
| normal_float_to_short_v3(f_no_s, &nors[i * 3]); | normal_float_to_short_v3(f_no_s, nors[i]); | ||||
| copy_v3_v3_short(&varray[start], f_no_s); | copy_v3_v3_short(&varray[start + 0], f_no_s); | ||||
| copy_v3_v3_short(&varray[start + 4], f_no_s); | copy_v3_v3_short(&varray[start + 4], f_no_s); | ||||
| copy_v3_v3_short(&varray[start + 8], f_no_s); | copy_v3_v3_short(&varray[start + 8], f_no_s); | ||||
| start += 12; | |||||
| if (f->v4) { | |||||
| copy_v3_v3_short(&varray[start], f_no_s); | |||||
| start += 4; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* calculate face normal */ | /* calculate face normal */ | ||||
| float f_no[3]; | float f_no[3]; | ||||
| short f_no_s[3]; | short f_no_s[3]; | ||||
| if (f->v4) | normal_tri_v3( | ||||
| normal_quad_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co, mvert[f->v4].co); | f_no, | ||||
| else | mvert[mloop[ltri[0]].v].co, | ||||
| normal_tri_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co); | mvert[mloop[ltri[1]].v].co, | ||||
| mvert[mloop[ltri[2]].v].co); | |||||
| normal_float_to_short_v3(f_no_s, f_no); | normal_float_to_short_v3(f_no_s, f_no); | ||||
| copy_v3_v3_short(&varray[start], f_no_s); | copy_v3_v3_short(&varray[start + 0], f_no_s); | ||||
| copy_v3_v3_short(&varray[start + 4], f_no_s); | copy_v3_v3_short(&varray[start + 4], f_no_s); | ||||
| copy_v3_v3_short(&varray[start + 8], f_no_s); | copy_v3_v3_short(&varray[start + 8], f_no_s); | ||||
| start += 12; | |||||
| if (f->v4) { | |||||
| copy_v3_v3_short(&varray[start], f_no_s); | |||||
| start += 4; | |||||
| } | |||||
| } | } | ||||
| start += 12; | |||||
| } | } | ||||
| } | } | ||||
| static void cdDM_buffer_copy_uv( | static void cdDM_buffer_copy_uv( | ||||
| DerivedMesh *dm, float *varray) | DerivedMesh *dm, float *varray) | ||||
| { | { | ||||
| int i, tottri; | |||||
| int start; | int start; | ||||
| int i, totface; | |||||
| MTFace *mtface; | const MLoopTri *lt; | ||||
| MFace *f; | const MLoopUV *mloopuv; | ||||
| if (!(mtface = DM_get_tessface_data_layer(dm, CD_MTFACE))) | if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { | ||||
| return; | return; | ||||
| f = dm->getTessFaceArray(dm); | } | ||||
| lt = dm->looptris.array; | |||||
| tottri = dm->looptris.num; | |||||
| start = 0; | start = 0; | ||||
| totface = dm->getNumTessFaces(dm); | for (i = 0; i < tottri; i++, lt++) { | ||||
| for (i = 0; i < totface; i++, f++) { | const unsigned int *ltri = lt->tri; | ||||
| /* v1 v2 v3 */ | /* v1 v2 v3 */ | ||||
| copy_v2_v2(&varray[start], mtface[i].uv[0]); | copy_v2_v2(&varray[start + 0], mloopuv[ltri[0]].uv); | ||||
| copy_v2_v2(&varray[start + 2], mtface[i].uv[1]); | copy_v2_v2(&varray[start + 2], mloopuv[ltri[1]].uv); | ||||
| copy_v2_v2(&varray[start + 4], mtface[i].uv[2]); | copy_v2_v2(&varray[start + 4], mloopuv[ltri[2]].uv); | ||||
| start += 6; | start += 6; | ||||
| if (f->v4) { | |||||
| /* v4 */ | |||||
| copy_v2_v2(&varray[start], mtface[i].uv[3]); | |||||
| start += 2; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void cdDM_buffer_copy_uv_texpaint( | static void cdDM_buffer_copy_uv_texpaint( | ||||
| DerivedMesh *dm, float *varray) | DerivedMesh *dm, float *varray) | ||||
| { | { | ||||
| int i, tottri; | |||||
| int start; | int start; | ||||
| int i, totface; | |||||
| const MPoly *mpoly; | |||||
| const MLoopTri *lt; | |||||
| int totmaterial = dm->totmat; | int totmaterial = dm->totmat; | ||||
| MTFace **mtface_base; | const MLoopUV **uv_base; | ||||
| MTFace *stencil_base; | const MLoopUV *uv_stencil_base; | ||||
| int stencil; | int stencil; | ||||
| MFace *mf; | |||||
| /* should have been checked for before, reassert */ | /* should have been checked for before, reassert */ | ||||
| BLI_assert(DM_get_tessface_data_layer(dm, CD_MTFACE)); | BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV)); | ||||
| mf = dm->getTessFaceArray(dm); | uv_base = MEM_mallocN(totmaterial * sizeof(*uv_base), "texslots"); | ||||
| mtface_base = MEM_mallocN(totmaterial * sizeof(*mtface_base), "texslots"); | |||||
| for (i = 0; i < totmaterial; i++) { | for (i = 0; i < totmaterial; i++) { | ||||
| mtface_base[i] = DM_paint_uvlayer_active_get(dm, i); | uv_base[i] = DM_paint_uvlayer_active_get_mloopuv(dm, i); | ||||
| } | } | ||||
| stencil = CustomData_get_stencil_layer(&dm->faceData, CD_MTFACE); | stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV); | ||||
| stencil_base = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, stencil); | uv_stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil); | ||||
| totface = dm->getNumTessFaces(dm); | mpoly = dm->getPolyArray(dm); | ||||
| lt = dm->looptris.array; | |||||
| tottri = dm->looptris.num; | |||||
| start = 0; | start = 0; | ||||
| for (i = 0; i < totface; i++, mf++) { | for (i = 0; i < tottri; i++, lt++) { | ||||
| int mat_i = mf->mat_nr; | const MPoly *mp = &mpoly[lt->poly]; | ||||
| const unsigned int *ltri = lt->tri; | |||||
| int mat_i = mp->mat_nr; | |||||
| /* v1 v2 v3 */ | /* v1 v2 v3 */ | ||||
| copy_v2_v2(&varray[start], mtface_base[mat_i][i].uv[0]); | copy_v2_v2(&varray[start + 0], uv_base[mat_i][ltri[0]].uv); | ||||
| copy_v2_v2(&varray[start + 2], stencil_base[i].uv[0]); | copy_v2_v2(&varray[start + 2], uv_stencil_base[ltri[0]].uv); | ||||
| copy_v2_v2(&varray[start + 4], mtface_base[mat_i][i].uv[1]); | copy_v2_v2(&varray[start + 4], uv_base[mat_i][ltri[1]].uv); | ||||
| copy_v2_v2(&varray[start + 6], stencil_base[i].uv[1]); | copy_v2_v2(&varray[start + 6], uv_stencil_base[ltri[1]].uv); | ||||
| copy_v2_v2(&varray[start + 8], mtface_base[mat_i][i].uv[2]); | copy_v2_v2(&varray[start + 8], uv_base[mat_i][ltri[2]].uv); | ||||
| copy_v2_v2(&varray[start + 10], stencil_base[i].uv[2]); | copy_v2_v2(&varray[start + 10], uv_stencil_base[ltri[2]].uv); | ||||
| start += 12; | start += 12; | ||||
| if (mf->v4) { | |||||
| /* v4 */ | |||||
| copy_v2_v2(&varray[start], mtface_base[mat_i][i].uv[3]); | |||||
| copy_v2_v2(&varray[start + 2], stencil_base[i].uv[3]); | |||||
| start += 4; | |||||
| } | |||||
| } | } | ||||
| MEM_freeN(mtface_base); | MEM_freeN(uv_base); | ||||
| } | |||||
| static void copy_mcol_uc3(unsigned char *v, const unsigned char *col) | |||||
| { | |||||
| v[0] = col[3]; | |||||
| v[1] = col[2]; | |||||
| v[2] = col[1]; | |||||
| } | } | ||||
| /* treat varray_ as an array of MCol, four MCol's per face */ | /* treat varray_ as an array of MCol, four MCol's per face */ | ||||
| static void cdDM_buffer_copy_mcol( | static void cdDM_buffer_copy_mcol( | ||||
| DerivedMesh *dm, unsigned char *varray, | DerivedMesh *dm, unsigned char *varray, | ||||
| const void *user_data) | const void *user_data) | ||||
| { | { | ||||
| int i, totface, start; | int i, tottri; | ||||
| const unsigned char *mcol = user_data; | int start; | ||||
| MFace *f = dm->getTessFaceArray(dm); | const MLoopTri *lt; | ||||
| const MLoopCol *mloopcol = user_data; | |||||
| totface = dm->getNumTessFaces(dm); | lt = dm->looptris.array; | ||||
| tottri = dm->looptris.num; | |||||
| start = 0; | start = 0; | ||||
| for (i = 0; i < totface; i++, f++) { | |||||
| for (i = 0; i < tottri; i++, lt++) { | |||||
| const unsigned int *ltri = lt->tri; | |||||
| /* v1 v2 v3 */ | /* v1 v2 v3 */ | ||||
| copy_mcol_uc3(&varray[start], &mcol[i * 16]); | copy_v3_v3_char((char *)&varray[start + 0], &mloopcol[ltri[0]].r); | ||||
| copy_mcol_uc3(&varray[start + 3], &mcol[i * 16 + 4]); | copy_v3_v3_char((char *)&varray[start + 3], &mloopcol[ltri[1]].r); | ||||
| copy_mcol_uc3(&varray[start + 6], &mcol[i * 16 + 8]); | copy_v3_v3_char((char *)&varray[start + 6], &mloopcol[ltri[2]].r); | ||||
| start += 9; | start += 9; | ||||
| if (f->v4) { | |||||
| /* v3 v4 v1 */ | |||||
| copy_mcol_uc3(&varray[start], &mcol[i * 16 + 12]); | |||||
| start += 3; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void cdDM_buffer_copy_edge( | static void cdDM_buffer_copy_edge( | ||||
| DerivedMesh *dm, unsigned int *varray) | DerivedMesh *dm, unsigned int *varray) | ||||
| { | { | ||||
| MEdge *medge, *medge_base; | MEdge *medge, *medge_base; | ||||
| int i, totedge, iloose, inorm, iloosehidden, inormhidden; | int i, totedge, iloose, inorm, iloosehidden, inormhidden; | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | static void cdDM_buffer_copy_edge( | ||||
| dm->drawObject->tot_loose_edge_drawn = tot_loose; | dm->drawObject->tot_loose_edge_drawn = tot_loose; | ||||
| dm->drawObject->loose_edge_offset = tot + tot_hidden; | dm->drawObject->loose_edge_offset = tot + tot_hidden; | ||||
| dm->drawObject->tot_edge_drawn = tot; | dm->drawObject->tot_edge_drawn = tot; | ||||
| } | } | ||||
| static void cdDM_buffer_copy_uvedge( | static void cdDM_buffer_copy_uvedge( | ||||
| DerivedMesh *dm, float *varray) | DerivedMesh *dm, float *varray) | ||||
| { | { | ||||
| MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); | int i, tottri; | ||||
| int i, j = 0; | int start; | ||||
| const MLoopTri *lt; | |||||
| const MLoopUV *mloopuv; | |||||
| if (!tf) | if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) { | ||||
| return; | return; | ||||
| } | |||||
| for (i = 0; i < dm->numTessFaceData; i++, tf++) { | lt = dm->looptris.array; | ||||
| MFace mf; | tottri = dm->looptris.num; | ||||
| dm->getTessFace(dm, i, &mf); | start = 0; | ||||
| copy_v2_v2(&varray[j], tf->uv[0]); | for (i = 0; i < tottri; i++, lt++) { | ||||
| copy_v2_v2(&varray[j + 2], tf->uv[1]); | const unsigned int *ltri = lt->tri; | ||||
| copy_v2_v2(&varray[j + 4], tf->uv[1]); | copy_v2_v2(&varray[start + 0], mloopuv[ltri[0]].uv); | ||||
| copy_v2_v2(&varray[j + 6], tf->uv[2]); | copy_v2_v2(&varray[start + 2], mloopuv[ltri[1]].uv); | ||||
| if (!mf.v4) { | copy_v2_v2(&varray[start + 4], mloopuv[ltri[1]].uv); | ||||
| copy_v2_v2(&varray[j + 8], tf->uv[2]); | copy_v2_v2(&varray[start + 6], mloopuv[ltri[2]].uv); | ||||
| copy_v2_v2(&varray[j + 10], tf->uv[0]); | |||||
| j += 12; | |||||
| } | |||||
| else { | |||||
| copy_v2_v2(&varray[j + 8], tf->uv[2]); | |||||
| copy_v2_v2(&varray[j + 10], tf->uv[3]); | |||||
| copy_v2_v2(&varray[j + 12], tf->uv[3]); | copy_v2_v2(&varray[start + 8], mloopuv[ltri[2]].uv); | ||||
| copy_v2_v2(&varray[j + 14], tf->uv[0]); | copy_v2_v2(&varray[start + 10], mloopuv[ltri[0]].uv); | ||||
| j += 16; | start += 12; | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void cdDM_copy_gpu_data( | static void cdDM_copy_gpu_data( | ||||
| DerivedMesh *dm, int type, void *varray_p, | DerivedMesh *dm, int type, void *varray_p, | ||||
| const int *mat_orig_to_new, const void *user_data) | const int *mat_orig_to_new, const void *user_data) | ||||
| { | { | ||||
| /* 'varray_p' cast is redundant but include for self-documentation */ | /* 'varray_p' cast is redundant but include for self-documentation */ | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index) | ||||
| lnk = &gdo->vert_points[vert_index]; | lnk = &gdo->vert_points[vert_index]; | ||||
| if (lnk->point_index == -1) { | if (lnk->point_index == -1) { | ||||
| lnk->point_index = point_index; | lnk->point_index = point_index; | ||||
| } | } | ||||
| } | } | ||||
| #endif /* USE_GPU_POINT_LINK */ | #endif /* USE_GPU_POINT_LINK */ | ||||
| static int tri_indices[2][3] = {{0, 1, 2}, {2, 3, 0}}; | |||||
| /* update the vert_points and triangle_to_mface fields with a new | /* update the vert_points and triangle_to_mface fields with a new | ||||
| * triangle */ | * triangle */ | ||||
| static void cdDM_drawobject_add_triangle(GPUDrawObject *gdo, | static void cdDM_drawobject_add_triangle( | ||||
| int v1, int v2, int v3, bool quad, int loopindex) | GPUDrawObject *gdo, | ||||
| const MLoop *mloop, | |||||
| const MLoopTri *lt, | |||||
| const int loop_index) | |||||
| { | { | ||||
| int i, v[3] = {v1, v2, v3}; | int i; | ||||
| int *tri_i = quad ? tri_indices[1] : tri_indices[0]; | for (i = 0; i < 3; i++) { | ||||
| for (i = 0; i < 3; i++) | cdDM_drawobject_add_vert_point(gdo, mloop[lt->tri[i]].v, loop_index + i); | ||||
| cdDM_drawobject_add_vert_point(gdo, v[i], loopindex + tri_i[i]); | } | ||||
| } | } | ||||
| /* for each vertex, build a list of points related to it; these lists | /* for each vertex, build a list of points related to it; these lists | ||||
| * are stored in an array sized to the number of vertices */ | * are stored in an array sized to the number of vertices */ | ||||
| static void cdDM_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface, int totmat) | static void cdDM_drawobject_init_vert_points( | ||||
| GPUDrawObject *gdo, | |||||
| const MPoly *mpoly, const MLoop *mloop, | |||||
| const MLoopTri *mlooptri, int mlooptri_num, | |||||
| int totmat) | |||||
| { | { | ||||
| GPUBufferMaterial *mat; | GPUBufferMaterial *mat; | ||||
| int i, *mat_orig_to_new; | int i, *mat_orig_to_new; | ||||
| int tot_loops = 0; | int tot_loops = 0; | ||||
| const MLoopTri *lt; | |||||
| mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat, | mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat, | ||||
| "GPUDrawObject.mat_orig_to_new"); | "GPUDrawObject.mat_orig_to_new"); | ||||
| /* allocate the array and space for links */ | /* allocate the array and space for links */ | ||||
| gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert, | gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert, | ||||
| "GPUDrawObject.vert_points"); | "GPUDrawObject.vert_points"); | ||||
| #ifdef USE_GPU_POINT_LINK | #ifdef USE_GPU_POINT_LINK | ||||
| gdo->vert_points_mem = MEM_callocN(sizeof(GPUVertPointLink) * gdo->tot_triangle_point, | gdo->vert_points_mem = MEM_callocN(sizeof(GPUVertPointLink) * gdo->tot_triangle_point, | ||||
| Show All 11 Lines | #endif | ||||
| /* -1 indicates the link is not yet used */ | /* -1 indicates the link is not yet used */ | ||||
| for (i = 0; i < gdo->totvert; i++) { | for (i = 0; i < gdo->totvert; i++) { | ||||
| #ifdef USE_GPU_POINT_LINK | #ifdef USE_GPU_POINT_LINK | ||||
| gdo->vert_points[i].link = NULL; | gdo->vert_points[i].link = NULL; | ||||
| #endif | #endif | ||||
| gdo->vert_points[i].point_index = -1; | gdo->vert_points[i].point_index = -1; | ||||
| } | } | ||||
| for (i = 0; i < totface; i++, f++) { | for (i = 0, lt = mlooptri; i < mlooptri_num; i++, lt++) { | ||||
| mat = &gdo->materials[mat_orig_to_new[f->mat_nr]]; | const MPoly *mp = &mpoly[lt->poly]; | ||||
| mat = &gdo->materials[mat_orig_to_new[mp->mat_nr]]; | |||||
| mat->polys[mat->counter++] = i; | mat->polys[mat->counter++] = i; | ||||
| /* add triangle */ | /* add triangle */ | ||||
| cdDM_drawobject_add_triangle(gdo, f->v1, f->v2, f->v3, false, tot_loops); | cdDM_drawobject_add_triangle(gdo, mloop, lt, tot_loops); | ||||
| mat->totelements += 3; | mat->totelements += 3; | ||||
| /* add second triangle for quads */ | |||||
| if (f->v4) { | |||||
| cdDM_drawobject_add_triangle(gdo, f->v3, f->v4, f->v1, true, tot_loops); | |||||
| mat->totelements += 3; | |||||
| tot_loops += 4; | |||||
| } | |||||
| else { | |||||
| tot_loops += 3; | tot_loops += 3; | ||||
| } | } | ||||
| } | |||||
| /* map any unused vertices to loose points */ | /* map any unused vertices to loose points */ | ||||
| for (i = 0; i < gdo->totvert; i++) { | for (i = 0; i < gdo->totvert; i++) { | ||||
| if (gdo->vert_points[i].point_index == -1) { | if (gdo->vert_points[i].point_index == -1) { | ||||
| gdo->vert_points[i].point_index = gdo->tot_triangle_point + gdo->tot_loose_point; | gdo->vert_points[i].point_index = gdo->tot_triangle_point + gdo->tot_loose_point; | ||||
| gdo->tot_loose_point++; | gdo->tot_loose_point++; | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(mat_orig_to_new); | MEM_freeN(mat_orig_to_new); | ||||
| } | } | ||||
| typedef struct { | typedef struct { | ||||
| int elements; | int elements; | ||||
| int loops; | int loops; | ||||
| int polys; | int polys; | ||||
| } GPUMaterialInfo; | } GPUMaterialInfo; | ||||
| /* see GPUDrawObject's structure definition for a description of the | /* see GPUDrawObject's structure definition for a description of the | ||||
| * data being initialized here */ | * data being initialized here */ | ||||
| static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm) | static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm) | ||||
| { | { | ||||
| GPUDrawObject *gdo; | GPUDrawObject *gdo; | ||||
| MFace *mface; | const MPoly *mpoly; | ||||
| const MLoop *mloop; | |||||
| const MLoopTri *looptri; | |||||
| int totmat = dm->totmat; | int totmat = dm->totmat; | ||||
| GPUMaterialInfo *mat_info; | GPUMaterialInfo *mat_info; | ||||
| int i, curmat, totelements, totface, totloops; | int i, curmat, totelements, looptri_num, totloops; | ||||
| /* object contains at least one material (default included) so zero means uninitialized dm */ | /* object contains at least one material (default included) so zero means uninitialized dm */ | ||||
| BLI_assert(totmat != 0); | BLI_assert(totmat != 0); | ||||
| mface = dm->getTessFaceArray(dm); | mpoly = dm->getPolyArray(dm); | ||||
| totface = dm->getNumTessFaces(dm); | mloop = dm->getLoopArray(dm); | ||||
| looptri = dm->looptris.array; | |||||
| looptri_num = dm->looptris.num; | |||||
| /* get the number of points used by each material, treating | /* get the number of points used by each material, treating | ||||
| * each quad as two triangles */ | * each quad as two triangles */ | ||||
| mat_info = MEM_callocN(sizeof(*mat_info) * totmat, "GPU_drawobject_new.mat_orig_to_new"); | mat_info = MEM_callocN(sizeof(*mat_info) * totmat, "GPU_drawobject_new.mat_orig_to_new"); | ||||
| for (i = 0; i < totface; i++) { | |||||
| mat_info[mface[i].mat_nr].polys++; | /* NOTE: could loop polys instead (faster) */ | ||||
| if (mface[i].v4) { | for (i = 0; i < looptri_num; i++) { | ||||
| mat_info[mface[i].mat_nr].elements += 6; | const int mat_nr = mpoly[looptri[i].poly].mat_nr; | ||||
| mat_info[mface[i].mat_nr].loops += 4; | mat_info[mat_nr].polys++; | ||||
| } | mat_info[mat_nr].elements += 3; | ||||
| else { | mat_info[mat_nr].loops += 3; | ||||
| mat_info[mface[i].mat_nr].elements += 3; | |||||
| mat_info[mface[i].mat_nr].loops += 3; | |||||
| } | |||||
| } | } | ||||
| /* create the GPUDrawObject */ | /* create the GPUDrawObject */ | ||||
| gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); | gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject"); | ||||
| gdo->totvert = dm->getNumVerts(dm); | gdo->totvert = dm->getNumVerts(dm); | ||||
| gdo->totedge = dm->getNumEdges(dm); | gdo->totedge = dm->getNumEdges(dm); | ||||
| /* count the number of materials used by this DerivedMesh */ | /* count the number of materials used by this DerivedMesh */ | ||||
| for (i = 0; i < totmat; i++) { | for (i = 0; i < totmat; i++) { | ||||
| Show All 22 Lines | for (i = 0, curmat = 0, totelements = 0, totloops = 0; i < totmat; i++) { | ||||
| } | } | ||||
| } | } | ||||
| gdo->tot_loop_verts = totloops; | gdo->tot_loop_verts = totloops; | ||||
| /* store total number of points used for triangles */ | /* store total number of points used for triangles */ | ||||
| gdo->tot_triangle_point = totelements; | gdo->tot_triangle_point = totelements; | ||||
| cdDM_drawobject_init_vert_points(gdo, mface, totface, totmat); | cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, looptri, looptri_num, totmat); | ||||
| MEM_freeN(mat_info); | MEM_freeN(mat_info); | ||||
| return gdo; | return gdo; | ||||
| } | } | ||||
| static void cdDM_foreachMappedVert( | static void cdDM_foreachMappedVert( | ||||
| DerivedMesh *dm, | DerivedMesh *dm, | ||||
| void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), | void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]), | ||||
| ▲ Show 20 Lines • Show All 128 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 545 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( | BKE_mesh_calc_normals_poly( | ||||
| cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), | 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 1,000 Lines • Show Last 20 Lines | |||||