diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 23 |
4 files changed, 32 insertions, 7 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index ff1c04fd00d..3afd7d851cb 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -184,6 +184,8 @@ struct DerivedMesh { DerivedMeshType type; float auto_bump_scale; DMDirtyFlag dirty; + int totmat; /* total materials. Will be valid only before object drawing. */ + struct Material **mat; /* material array. Will be valid only before object drawing */ /* use for converting to BMesh which doesn't store bevel weight and edge crease by default */ char cd_flag; @@ -578,6 +580,7 @@ void DM_ensure_tessface(DerivedMesh *dm); void DM_update_tessface_data(DerivedMesh *dm); +void DM_update_materials(DerivedMesh *dm, struct Object *ob); /** interpolates vertex data from the vertices indexed by src_indices in the * source mesh using the given weights and stores the result in the vertex * indexed by dest_index in the dest mesh diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 1a9ca234f8d..dcaf102ef01 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -54,6 +54,7 @@ #include "BKE_displist.h" #include "BKE_editmesh.h" #include "BKE_key.h" +#include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" @@ -482,6 +483,13 @@ void DM_update_tessface_data(DerivedMesh *dm) dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS; } +void DM_update_materials(DerivedMesh *dm, Object *ob) +{ + dm->totmat = ob->totcol + 1; /* materials start from 1, default material is 0 */ + dm->mat = *give_matarar(ob); +} + + void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) { /* dm might depend on me, so we need to do everything with a local copy */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 61866b60a8c..e7f94485664 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3419,6 +3419,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if (!dm) return; + DM_update_materials(dm, ob); + /* Check to draw dynamic paint colors (or weights from WeightVG modifiers). * Note: Last "preview-active" modifier in stack will win! */ if (DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL) && modifiers_isPreview(ob)) @@ -3707,6 +3709,9 @@ static bool draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3 cageDM = editbmesh_get_derived_cage_and_final(scene, ob, em, &finalDM, scene->customdata_mask); + DM_update_materials(finalDM, ob); + DM_update_materials(cageDM, ob); + if (dt > OB_WIRE) { const bool glsl = draw_glsl_material(scene, ob, v3d, dt); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 22cfc712df3..dc986badb16 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -422,11 +422,13 @@ static void gpu_drawobject_add_triangle(GPUDrawObject *gdo, /* for each vertex, build a list of points related to it; these lists * are stored in an array sized to the number of vertices */ -static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface) +static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int totface, int totmat) { GPUBufferMaterial *mat; - int i, mat_orig_to_new[MAX_MATERIALS]; + int i, *mat_orig_to_new; + mat_orig_to_new = MEM_callocN(sizeof(*mat_orig_to_new) * totmat, + "GPUDrawObject.mat_orig_to_new"); /* allocate the array and space for links */ gdo->vert_points = MEM_callocN(sizeof(GPUVertPointLink) * gdo->totvert, "GPUDrawObject.vert_points"); @@ -466,6 +468,8 @@ static void gpu_drawobject_init_vert_points(GPUDrawObject *gdo, MFace *f, int to gdo->tot_loose_point++; } } + + MEM_freeN(mat_orig_to_new); } /* see GPUDrawObject's structure definition for a description of the @@ -474,15 +478,19 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm) { GPUDrawObject *gdo; MFace *mface; - int points_per_mat[MAX_MATERIALS]; + int totmat = dm->totmat; + int *points_per_mat; int i, curmat, curpoint, totface; + /* object contains at least one material (default included) so zero means uninitialized dm */ + BLI_assert(totmat != 0); + mface = dm->getTessFaceArray(dm); totface = dm->getNumTessFaces(dm); /* get the number of points used by each material, treating * each quad as two triangles */ - memset(points_per_mat, 0, sizeof(int) * MAX_MATERIALS); + points_per_mat = MEM_callocN(sizeof(*points_per_mat) * totmat, "GPU_drawobject_new.mat_orig_to_new"); for (i = 0; i < totface; i++) points_per_mat[mface[i].mat_nr] += mface[i].v4 ? 6 : 3; @@ -492,7 +500,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm) gdo->totedge = dm->getNumEdges(dm); /* count the number of materials used by this DerivedMesh */ - for (i = 0; i < MAX_MATERIALS; i++) { + for (i = 0; i < totmat; i++) { if (points_per_mat[i] > 0) gdo->totmaterial++; } @@ -502,7 +510,7 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm) "GPUDrawObject.materials"); /* initialize the materials array */ - for (i = 0, curmat = 0, curpoint = 0; i < MAX_MATERIALS; i++) { + for (i = 0, curmat = 0, curpoint = 0; i < totmat; i++) { if (points_per_mat[i] > 0) { gdo->materials[curmat].start = curpoint; gdo->materials[curmat].totpoint = 0; @@ -519,7 +527,8 @@ GPUDrawObject *GPU_drawobject_new(DerivedMesh *dm) gdo->triangle_to_mface = MEM_mallocN(sizeof(int) * (gdo->tot_triangle_point / 3), "GPUDrawObject.triangle_to_mface"); - gpu_drawobject_init_vert_points(gdo, mface, totface); + gpu_drawobject_init_vert_points(gdo, mface, totface, totmat); + MEM_freeN(points_per_mat); return gdo; } |