forked from bartvdbraak/blender
GPU buffer materials:
Separate and reuse some shared code. Also avoid counting for information we already know, such as total loop triangles etc.
This commit is contained in:
parent
38e19536bf
commit
50a46a5973
@ -1652,12 +1652,6 @@ static void cdDM_drawobject_init_vert_points(
|
||||
MEM_freeN(mat_orig_to_new);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int elements;
|
||||
int loops;
|
||||
int polys;
|
||||
} GPUMaterialInfo;
|
||||
|
||||
/* see GPUDrawObject's structure definition for a description of the
|
||||
* data being initialized here */
|
||||
static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
|
||||
@ -1666,8 +1660,8 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
|
||||
const MPoly *mpoly;
|
||||
const MLoop *mloop;
|
||||
int totmat = dm->totmat;
|
||||
GPUMaterialInfo *mat_info;
|
||||
int i, curmat, totelements, totloops, totpolys;
|
||||
GPUBufferMaterial *mat_info;
|
||||
int i, totloops, totpolys;
|
||||
|
||||
/* object contains at least one material (default included) so zero means uninitialized dm */
|
||||
BLI_assert(totmat != 0);
|
||||
@ -1676,6 +1670,7 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
|
||||
mloop = dm->getLoopArray(dm);
|
||||
|
||||
totpolys = dm->getNumPolys(dm);
|
||||
totloops = dm->getNumLoops(dm);
|
||||
|
||||
/* get the number of points used by each material, treating
|
||||
* each quad as two triangles */
|
||||
@ -1683,49 +1678,23 @@ static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
|
||||
|
||||
for (i = 0; i < totpolys; i++) {
|
||||
const int mat_nr = mpoly[i].mat_nr;
|
||||
mat_info[mat_nr].polys++;
|
||||
mat_info[mat_nr].elements += 3 * ME_POLY_TRI_TOT(&mpoly[i]);
|
||||
mat_info[mat_nr].loops += mpoly[i].totloop;
|
||||
mat_info[mat_nr].totpolys++;
|
||||
mat_info[mat_nr].totelements += 3 * ME_POLY_TRI_TOT(&mpoly[i]);
|
||||
mat_info[mat_nr].totloops += mpoly[i].totloop;
|
||||
}
|
||||
/* create the GPUDrawObject */
|
||||
gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
|
||||
gdo->totvert = dm->getNumVerts(dm);
|
||||
gdo->totedge = dm->getNumEdges(dm);
|
||||
|
||||
/* count the number of materials used by this DerivedMesh */
|
||||
for (i = 0; i < totmat; i++) {
|
||||
if (mat_info[i].elements > 0)
|
||||
gdo->totmaterial++;
|
||||
}
|
||||
|
||||
/* allocate an array of materials used by this DerivedMesh */
|
||||
gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial,
|
||||
"GPUDrawObject.materials");
|
||||
|
||||
/* initialize the materials array */
|
||||
for (i = 0, curmat = 0, totelements = 0, totloops = 0; i < totmat; i++) {
|
||||
if (mat_info[i].elements > 0) {
|
||||
gdo->materials[curmat].start = totelements;
|
||||
/* can set it to points now but used in cdDM_drawobject_init_vert_points as counter */
|
||||
gdo->materials[curmat].totelements = mat_info[i].elements;
|
||||
gdo->materials[curmat].totloops = mat_info[i].loops;
|
||||
gdo->materials[curmat].mat_nr = i;
|
||||
gdo->materials[curmat].totpolys = mat_info[i].polys;
|
||||
gdo->materials[curmat].polys = MEM_mallocN(sizeof(int) * mat_info[i].polys, "GPUBufferMaterial.polys");
|
||||
|
||||
totelements += mat_info[i].elements;
|
||||
totloops += mat_info[i].loops;
|
||||
curmat++;
|
||||
}
|
||||
}
|
||||
GPU_buffer_material_finalize(gdo, mat_info, totmat);
|
||||
|
||||
gdo->tot_loop_verts = totloops;
|
||||
|
||||
/* store total number of points used for triangles */
|
||||
gdo->tot_triangle_point = totelements;
|
||||
gdo->tot_triangle_point = dm->getNumLoopTri(dm) * 3;
|
||||
|
||||
cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, totpolys, totmat);
|
||||
MEM_freeN(mat_info);
|
||||
|
||||
return gdo;
|
||||
}
|
||||
|
@ -2458,12 +2458,6 @@ static void ccgDM_copy_gpu_data(
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int elements;
|
||||
int loops;
|
||||
int polys;
|
||||
} GPUMaterialInfo;
|
||||
|
||||
static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
{
|
||||
GPUBufferMaterial *mat;
|
||||
@ -2474,8 +2468,8 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
DMFlagMat *faceFlags = ccgdm->faceFlags;
|
||||
int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
|
||||
int totmat = (faceFlags) ? dm->totmat : 1;
|
||||
GPUMaterialInfo *matinfo;
|
||||
int i, curmat, curelement;
|
||||
GPUBufferMaterial *matinfo;
|
||||
int i;
|
||||
unsigned int tot_internal_edges = 0;
|
||||
int edgeVerts = ccgSubSurf_getEdgeSize(ss);
|
||||
int edgeSize = edgeVerts - 1;
|
||||
@ -2494,9 +2488,9 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
int numVerts = ccgSubSurf_getFaceNumVerts(f);
|
||||
int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
|
||||
int new_matnr = faceFlags[index].mat_nr;
|
||||
matinfo[new_matnr].elements += numVerts * gridFaces * gridFaces * 6;
|
||||
matinfo[new_matnr].loops += numVerts * gridFaces * gridFaces * 4;
|
||||
matinfo[new_matnr].polys++;
|
||||
matinfo[new_matnr].totelements += numVerts * gridFaces * gridFaces * 6;
|
||||
matinfo[new_matnr].totloops += numVerts * gridFaces * gridFaces * 4;
|
||||
matinfo[new_matnr].totpolys++;
|
||||
tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
|
||||
}
|
||||
}
|
||||
@ -2504,9 +2498,9 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
for (i = 0; i < totface; i++) {
|
||||
CCGFace *f = ccgdm->faceMap[i].face;
|
||||
int numVerts = ccgSubSurf_getFaceNumVerts(f);
|
||||
matinfo[0].elements += numVerts * gridFaces * gridFaces * 6;
|
||||
matinfo[0].loops += numVerts * gridFaces * gridFaces * 4;
|
||||
matinfo[0].polys++;
|
||||
matinfo[0].totelements += numVerts * gridFaces * gridFaces * 6;
|
||||
matinfo[0].totloops += numVerts * gridFaces * gridFaces * 4;
|
||||
matinfo[0].totpolys++;
|
||||
tot_internal_edges += numVerts * gridFaces * (2 * gridFaces - 1);
|
||||
}
|
||||
}
|
||||
@ -2516,33 +2510,10 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
gdo->totvert = 0; /* used to count indices, doesn't really matter for ccgsubsurf */
|
||||
gdo->totedge = (totedge * edgeSize + tot_internal_edges);
|
||||
|
||||
/* count the number of materials used by this DerivedMesh */
|
||||
for (i = 0; i < totmat; i++) {
|
||||
if (matinfo[i].elements > 0)
|
||||
gdo->totmaterial++;
|
||||
}
|
||||
|
||||
/* allocate an array of materials used by this DerivedMesh */
|
||||
gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial,
|
||||
"GPUDrawObject.materials");
|
||||
|
||||
/* initialize the materials array */
|
||||
for (i = 0, curmat = 0, curelement = 0; i < totmat; i++) {
|
||||
if (matinfo[i].elements > 0) {
|
||||
gdo->materials[curmat].start = curelement;
|
||||
gdo->materials[curmat].totelements = matinfo[i].elements;
|
||||
gdo->materials[curmat].totloops = matinfo[i].loops;
|
||||
gdo->materials[curmat].mat_nr = i;
|
||||
gdo->materials[curmat].totpolys = matinfo[i].polys;
|
||||
gdo->materials[curmat].polys = MEM_mallocN(sizeof(int) * matinfo[i].polys, "GPUBufferMaterial.polys");
|
||||
|
||||
curelement += matinfo[i].elements;
|
||||
curmat++;
|
||||
}
|
||||
}
|
||||
GPU_buffer_material_finalize(gdo, matinfo, totmat);
|
||||
|
||||
/* store total number of points used for triangles */
|
||||
gdo->tot_triangle_point = curelement;
|
||||
gdo->tot_triangle_point = ccgSubSurf_getNumFinalFaces(ss) * 6;
|
||||
|
||||
gdo->tot_loop_verts = ccgSubSurf_getNumFinalFaces(ss) * 4;
|
||||
|
||||
@ -2582,7 +2553,6 @@ static GPUDrawObject *ccgDM_GPUObjectNew(DerivedMesh *dm)
|
||||
}
|
||||
|
||||
MEM_freeN(mat_orig_to_new);
|
||||
MEM_freeN(matinfo);
|
||||
|
||||
return gdo;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ struct DMFlagMat;
|
||||
struct DerivedMesh;
|
||||
struct GSet;
|
||||
struct GPUVertPointLink;
|
||||
struct GPUDrawObject;
|
||||
struct PBVH;
|
||||
struct MVert;
|
||||
|
||||
@ -71,6 +72,8 @@ typedef struct GPUBufferMaterial {
|
||||
short mat_nr;
|
||||
} GPUBufferMaterial;
|
||||
|
||||
void GPU_buffer_material_finalize(struct GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat);
|
||||
|
||||
/* meshes are split up by material since changing materials requires
|
||||
* GL state changes that can't occur in the middle of drawing an
|
||||
* array.
|
||||
|
@ -114,6 +114,36 @@ static int mres_prev_gridsize = -1;
|
||||
static GLenum mres_prev_index_type = 0;
|
||||
static unsigned mres_prev_totquad = 0;
|
||||
|
||||
void GPU_buffer_material_finalize(GPUDrawObject *gdo, GPUBufferMaterial *matinfo, int totmat)
|
||||
{
|
||||
int i, curmat, curelement;
|
||||
|
||||
/* count the number of materials used by this DerivedMesh */
|
||||
for (i = 0; i < totmat; i++) {
|
||||
if (matinfo[i].totelements > 0)
|
||||
gdo->totmaterial++;
|
||||
}
|
||||
|
||||
/* allocate an array of materials used by this DerivedMesh */
|
||||
gdo->materials = MEM_mallocN(sizeof(GPUBufferMaterial) * gdo->totmaterial,
|
||||
"GPUDrawObject.materials");
|
||||
|
||||
/* initialize the materials array */
|
||||
for (i = 0, curmat = 0, curelement = 0; i < totmat; i++) {
|
||||
if (matinfo[i].totelements > 0) {
|
||||
gdo->materials[curmat] = matinfo[i];
|
||||
gdo->materials[curmat].start = curelement;
|
||||
gdo->materials[curmat].mat_nr = i;
|
||||
gdo->materials[curmat].polys = MEM_mallocN(sizeof(int) * matinfo[i].totpolys, "GPUBufferMaterial.polys");
|
||||
|
||||
curelement += matinfo[i].totelements;
|
||||
curmat++;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(matinfo);
|
||||
}
|
||||
|
||||
|
||||
/* stores recently-deleted buffers so that new buffers won't have to
|
||||
* be recreated as often
|
||||
|
Loading…
Reference in New Issue
Block a user