- added mesh_get_derived_render

- cancelled previous commit to add RE_findTFAce, instead just added
   a MemArena to render struct... free'd at end of render, can be used
   to store other data as well
 - switch rendering to using DerivedMesh API... this is slightly more
   inefficient now because it is doing some unnecessary copying. Can
   be fixed by defining a DerivedMesh function to convert the object
   into a render object (on todo list)
This commit is contained in:
Daniel Dunbar 2005-03-28 21:49:49 +00:00
parent 7dbb253908
commit 67eaf69f3f
7 changed files with 102 additions and 95 deletions

@ -50,6 +50,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_subsurf.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@ -642,6 +643,8 @@ typedef struct {
DispListMesh *dlm;
EditMesh *em;
int needsFree;
} SSDerivedMesh;
static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
@ -1013,7 +1016,18 @@ static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm)
return displistmesh_copy(ssdm->dlm);
}
static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm)
static void ssDM_release(DerivedMesh *dm)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
if (ssdm->needsFree) {
displistmesh_free(ssdm->dlm);
}
MEM_freeN(dm);
}
static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm, int needsFree)
{
SSDerivedMesh *ssdm = MEM_mallocN(sizeof(*ssdm), "dm");
@ -1039,10 +1053,11 @@ static DerivedMesh *getSSDerivedMesh(EditMesh *em, DispListMesh *dlm)
ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
ssdm->dm.drawFacesEM = ssDM_drawFacesEM;
ssdm->dm.release = MEM_freeN;
ssdm->dm.release = ssDM_release;
ssdm->dlm = dlm;
ssdm->em = em;
ssdm->needsFree = needsFree;
return (DerivedMesh*) ssdm;
}
@ -1081,18 +1096,51 @@ DerivedMesh *mesh_get_derived(Object *ob)
build_mesh_data(ob);
dl= find_displist(&me->disp, DL_MESH);
if(dl) {
// XXX, This test should not be here because
// build_mesh_data should have made DLM... problem
// is there is an exception for objects from dupli,
// they only get displist built for first object.
//
// Would work fine except countall gets a derived
// mesh before the displist has been evaluated.
if (dl) {
if(G.obedit && me==G.obedit->data) {
return getSSDerivedMesh(G.editMesh, dl->mesh);
return getSSDerivedMesh(G.editMesh, dl->mesh, 0);
} else {
return getSSDerivedMesh(NULL, dl->mesh);
return getSSDerivedMesh(NULL, dl->mesh, 0);
}
}
}
return NULL;
}
DerivedMesh *mesh_get_derived_render(Object *ob)
{
Mesh *me= ob->data;
if (mesh_uses_displist(me)) {
if (me->subdiv==me->subdivr) {
DispList *dl= find_displist(&me->disp, DL_MESH);
if(G.obedit && me==G.obedit->data) {
return getSSDerivedMesh(G.editMesh, dl->mesh, 0);
} else {
return getSSDerivedMesh(NULL, dl->mesh, 0);
}
} else {
if(G.obedit && me==G.obedit->data) {
DispListMesh *dlm = subsurf_make_dispListMesh_from_editmesh(G.editMesh, me->subdivr, me->flag, me->subsurftype);
return getSSDerivedMesh(G.editMesh, dlm, 1);
} else {
DispListMesh *dlm = subsurf_make_dispListMesh_from_mesh(me, me->subdivr, me->flag);
return getSSDerivedMesh(NULL, dlm, 1);
}
}
else return NULL;
} else {
return NULL;
}
return NULL;
}
DerivedMesh *mesh_get_base_derived(Object *ob)

@ -44,7 +44,7 @@
* enough to not cause much internal fragmentation,
* small enough not to waste resources
*/
#define BLI_MEMARENA_STD_BUFSIZE 4096
#define BLI_MEMARENA_STD_BUFSIZE (1<<14)
struct MemArena;
typedef struct MemArena MemArena;

@ -191,7 +191,6 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
struct VlakRen *RE_findOrAddVlak(int nr);
struct VertRen *RE_findOrAddVert(int nr);
struct HaloRen *RE_findOrAddHalo(int nr);
struct TFace *RE_findTFace(void);
HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize,
float vectsize, int seed);

@ -51,17 +51,6 @@
/* ------------------------------------------------------------------------- */
struct TFace;
typedef struct TFaceBlock TFaceBlock;
struct TFaceBlock {
TFaceBlock *next;
struct TFace *tfaces;
int numAvail;
};
/* localized texture result data */
typedef struct TexResult {
float tin, tr, tg, tb, ta;
@ -111,6 +100,8 @@ typedef struct ShadeInput
} ShadeInput;
struct MemArena;
/* here only stuff to initalize the render itself */
typedef struct RE_Render
{
@ -150,7 +141,11 @@ typedef struct RE_Render
struct VlakRen **blovl;
struct VertRen **blove;
struct HaloRen **bloha;
struct TFaceBlock *tfaceBlocks;
/* arena for allocating data for use during render, for
* example dynamic TFaces to go in the VlakRen structure.
*/
struct MemArena *memArena;
int *rectaccu;
int *rectz; /* z buffer: distance buffer */

@ -442,14 +442,6 @@ void RE_init_render_data(void)
void RE_free_render_data()
{
TFaceBlock *tfb;
while (tfb = R.tfaceBlocks) {
R.tfaceBlocks = tfb->next;
MEM_freeN(tfb->tfaces);
MEM_freeN(tfb);
}
MEM_freeN(R.blove);
R.blove= NULL;
MEM_freeN(R.blovl);

@ -174,26 +174,6 @@ VlakRen *RE_findOrAddVlak(int nr)
return v;
}
/* ------------------------------------------------------------------------ */
TFace *RE_findTFace(void)
{
TFaceBlock *tfb = R.tfaceBlocks;
if (!tfb || !tfb->numAvail) {
TFaceBlock *tfbn = MEM_mallocN(sizeof(*tfbn), "TFaceBlock");
tfbn->tfaces = MEM_mallocN(sizeof(*tfbn->tfaces)*TABLEINITSIZE, "TFaceBlock->tfaces");
tfbn->numAvail = TABLEINITSIZE;
tfbn->next = R.tfaceBlocks;
R.tfaceBlocks = tfbn;
tfb = tfbn;
}
return &tfb->tfaces[tfb->numAvail--];
}
/* ------------------------------------------------------------------------- */
HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1,

@ -51,6 +51,7 @@
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
#include "BLI_rand.h"
#include "BLI_memarena.h"
#include "DNA_scene_types.h"
#include "DNA_lamp_types.h"
@ -75,6 +76,7 @@
#include "BKE_constraint.h"
#include "BKE_displist.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_key.h"
@ -1297,8 +1299,6 @@ static void init_render_mesh(Object *ob)
Material *ma;
MSticky *ms = NULL;
PartEff *paf;
DispList *dl;
// TFace *tface;
unsigned int *vertcol;
float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3],
float *extverts=0, *orco;
@ -1354,40 +1354,17 @@ static void init_render_mesh(Object *ob)
do_puno= mesh_modifier(ob, 's');
if (mesh_uses_displist(me)) {
dl= me->disp.first;
DerivedMesh *dm = mesh_get_derived_render(ob);
dlm = dm->convertToDispListMesh(dm);
dm->release(dm);
/* Force a displist rebuild if this is a subsurf and we have a different subdiv level */
/* also when object is in editmode, displist ordering for editmode is different, giving orco probs */
if((dl==NULL) || ((me->subdiv != me->subdivr)) || (G.obedit && me==G.obedit->data)) {
/* prevent subsurf called again for duplicate use of mesh, tface pointers change */
if(dl==NULL || (me->subdivdone-1)!=me->subdivr) {
dlm= subsurf_make_dispListMesh_from_mesh(me, me->subdivr, me->flag);
dl= MEM_callocN(sizeof(*dl), "dl");
dl->type= DL_MESH;
dl->mesh= dlm;
mvert= dlm->mvert;
totvert= dlm->totvert;
free_displist_by_type(&me->disp, DL_MESH);
BLI_addtail(&me->disp, dl);
me->subdivdone= me->subdivr+1; /* stupid hack, add one because otherwise old files will get
* subdivdone==0, so me->subdivr==0 won't work. proper caching
* will remove this hack.
*/
}
}
if(dl==NULL || dl->type!=DL_MESH); // here used to be a return, but why?
else {
dlm= dl->mesh;
mvert= dlm->mvert;
totvert= dlm->totvert;
ms= NULL; // no stick in displistmesh
}
ms= NULL; // no stick in displistmesh
} else {
DispList *dl;
dlm= NULL;
mvert= me->mvert;
totvert= me->totvert;
@ -1473,7 +1450,7 @@ static void init_render_mesh(Object *ob)
mface= dlm->mface + start;
if (dlm->tface) {
tface= dlm->tface + start;
vertcol= dlm->tface->col;
vertcol= NULL;
} else if (dlm->mcol) {
vertcol= (unsigned int *)dlm->mcol;
} else {
@ -1483,7 +1460,7 @@ static void init_render_mesh(Object *ob)
mface= ((MFace*) me->mface) + start;
if (me->tface) {
tface= ((TFace*) me->tface) + start;
vertcol= ((TFace*) me->tface)->col;
vertcol= NULL;
} else if (me->mcol) {
vertcol= (unsigned int *)me->mcol;
} else {
@ -1532,15 +1509,25 @@ static void init_render_mesh(Object *ob)
if(len==0) R.totvlak--;
else {
if(vertcol) {
if(tface) vlr->vcol= vertcol+sizeof(TFace)*a/4; /* vertcol is int */
else vlr->vcol= vertcol+sizeof(int)*a;
if(dlm) {
if(tface) {
vlr->tface= BLI_memarena_alloc(R.memArena, sizeof(*vlr->tface));
vlr->vcol= vlr->tface->col;
memcpy(vlr->tface, tface, sizeof(*tface));
}
else if (vertcol) {
vlr->vcol= BLI_memarena_alloc(R.memArena, sizeof(int)*16);
memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*16);
}
} else {
if(tface) {
vlr->vcol= tface->col;
vlr->tface= tface;
}
else if (vertcol) {
vlr->vcol= vertcol+4*a;
}
}
else vlr->vcol= 0;
vlr->tface= tface;
}
}
else if(v2 && (ma->mode & MA_WIRE)) {
@ -1606,6 +1593,8 @@ static void init_render_mesh(Object *ob)
if(do_puno) calc_vertexnormals(totverto, totvlako);
mesh_modifier(ob, 'e'); // end
if(dlm) displistmesh_free(dlm);
}
/* ------------------------------------------------------------------------- */
@ -2685,6 +2674,9 @@ void RE_freeRotateBlenderScene(void)
char *ctile;
/* FREE */
BLI_memarena_free(R.memArena);
R.memArena = NULL;
for(a=0; a<R.totlamp; a++) {
if(R.la[a]->shb) {
@ -2745,7 +2737,6 @@ void RE_freeRotateBlenderScene(void)
if (mesh_uses_displist(me) && ((me->subdiv!=me->subdivr) || (ob->effect.first != NULL) || ob==G.obedit) ) {
/* Need to recalc for effects since they are time dependant */
makeDispList(ob); /* XXX this should be replaced with proper caching */
me->subdivdone= 0; /* needed to prevent multiple used meshes being recalculated */
}
}
else if(ob->type==OB_MBALL) {
@ -2919,6 +2910,8 @@ void RE_rotateBlenderScene(void)
if(G.scene->camera==0) return;
R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
slurph_opt= 0;
R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;