This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/render/intern/source/zbufferdatastruct.c
Kent Mein d0e346d544 updated .c files to include:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

Just need to finish cpp files now :)

Kent
--
mein@cs.umn.edu
2002-11-25 12:02:15 +00:00

348 lines
9.6 KiB
C

/**
* zbufferdatastruct.c
*
* $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*
* The z buffer consists of an array of lists. Each list holds the objects
* behind a pixel. These can be sorted for closest distance. Per object,
* we store:
* - object type
* - object index
* - minimum distance
* - maximum distance
* - oversample flags
*
* The buffer was created to fit the new unified renderpipeline. We might
* turn it into an object later on.
*
* The z buffer has an unlimited depth. The oversampling code chops at a
* certain number of faces. This number is defined in
* vanillaRenderPipe_types.h
*
* Version 1 of the z buffer inserted objects by means of linear
* search: we walk along the list until we find the right object or
* until we have to insert a new one. This is terribly inefficient
* when we are dealing with large numbers of objects. Can we find a
* better solution here?
*
* Because we treat halos as billboards, we optimize halo
* insertion. For this purpose the fillFlatObject() functions have
* been implemented. */
#include <string.h>
#include "MEM_guardedalloc.h"
#include "zbufferdatastruct.h"
#include "render.h"
#include "render_intern.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* if defined: all jittersamples are stored individually. _very_ serious */
/* performance hit ! also gives some buffer size problems in big scenes */
/* #define RE_INDIVIDUAL_SUBPIXELS */
/* ------------------------------------------------------------------------- */
static RE_APixstrExtMain RE_apsemfirst; /* pixstr bookkeeping var */
static short RE_apsemteller = 0; /* pixstr bookkeeping var */
static int RE_zbufferwidth; /* width of the z-buffer (pixels) */
RE_APixstrExt *APixbufExt; /* Zbuffer: linked list of face, halo indices */
/*-RE_APixstrExt------------------------------------------------------------ */
void initZbuffer(int width)
{
APixbufExt = MEM_callocN(RE_ZBUFLEN * width * sizeof(RE_APixstrExt),
"APixbufExt");
RE_zbufferwidth = width;
RE_apsemteller = 0;
RE_apsemfirst.next = NULL;
RE_apsemfirst.ps = NULL;
} /* end of RE_APixstrExt *initZbufferDataStruct() */
/* ------------------------------------------------------------------------- */
void freeZbuffer(void)
{
if (APixbufExt) MEM_freeN(APixbufExt);
freepseA();
} /* end of void freeZbuffer(void) */
/* ------------------------------------------------------------------------- */
void resetZbuffer(void)
{
int len;
freepseA();
len = sizeof(RE_APixstrExt) * RE_zbufferwidth * RE_ZBUFLEN;
memset(APixbufExt, 0, len);
} /* end of void resetZbuffer(void) */
/* ------------------------------------------------------------------------- */
RE_APixstrExt *addpsemainA()
{
RE_APixstrExtMain *psm;
psm= &RE_apsemfirst;
while(psm->next) {
psm= psm->next;
}
psm->next= MEM_callocN(sizeof(RE_APixstrExtMain), "addpsemainA");
psm= psm->next;
/* Initialise the new structure to safe values. Memory that is newly */
/* allocated must be zero... Not sure if that happens everywhere now.*/
psm->next=0;
psm->ps= MEM_callocN(4096*sizeof(RE_APixstrExt),"pixstrext");
RE_apsemteller= 0;
return psm->ps;
} /* End of RE_APixstrExt *addpsemainA() */
/* ------------------------------------------------------------------------- */
void freepseA()
{
RE_APixstrExtMain *psm, *next;
psm= &RE_apsemfirst;
while(psm) {
next= psm->next;
if(psm->ps) {
MEM_freeN(psm->ps);
psm->ps= 0;
}
if(psm!= &RE_apsemfirst) MEM_freeN(psm);
psm= next;
}
RE_apsemfirst.next= 0;
RE_apsemfirst.ps= 0;
RE_apsemteller= 0;
} /* End of void freepseA() */
/* ------------------------------------------------------------------------- */
RE_APixstrExt *addpseA(void)
{
static RE_APixstrExt *prev;
/* eerste PS maken */
if((RE_apsemteller & 4095)==0) prev= addpsemainA();
else prev++;
RE_apsemteller++;
return prev;
} /* End of RE_APixstrExt *addpseA(void) */
/* ------------------------------------------------------------------------- */
void insertObject(int apteller,
/* int opaque, */
int obindex,
int obtype,
int dist,
int mask)
{
/* Guard the insertion if needed? */
RE_APixstrExt* apn = &APixbufExt[apteller];
while(apn) {
if(apn->t[0] == RE_NONE) {
apn->p[0] = obindex; apn->t[0] = obtype;
apn->zmin[0] = dist; apn->zmax[0] = dist;
apn->mask[0] = mask;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if((apn->p[0] == obindex) && (apn->t[0] & obtype)) {
if(dist < apn->zmin[0]) apn->zmin[0] = dist;
else if(dist > apn->zmax[0]) apn->zmax[0] = dist;
apn->mask[0]|= mask;
break;
}
#endif
if(apn->t[1] == RE_NONE) {
apn->p[1] = obindex; apn->t[1] = obtype;
apn->zmin[1] = dist; apn->zmax[1] = dist;
apn->mask[1] = mask;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if((apn->p[1] == obindex) && (apn->t[1] & obtype)) {
if(dist < apn->zmin[1]) apn->zmin[1] = dist;
else if(dist > apn->zmax[1]) apn->zmax[1] = dist;
apn->mask[1]|= mask;
break;
}
#endif
if(apn->t[2] == RE_NONE) {
apn->p[2] = obindex; apn->t[2] = obtype;
apn->zmin[2] = dist; apn->zmax[2] = dist;
apn->mask[2] = mask;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if((apn->p[2] == obindex) && (apn->t[2] & obtype)) {
if(dist < apn->zmin[2]) apn->zmin[2] = dist;
else if(dist > apn->zmax[2]) apn->zmax[2] = dist;
apn->mask[2]|= mask;
break;
}
#endif
if(apn->t[3] == RE_NONE) {
apn->p[3] = obindex; apn->t[3] = obtype;
apn->zmin[3] = dist; apn->zmax[3] = dist;
apn->mask[3] = mask;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if((apn->p[3] == obindex) && (apn->t[3] & obtype)) {
if(dist < apn->zmin[3]) apn->zmin[3] = dist;
else if(dist > apn->zmax[3]) apn->zmax[3] = dist;
apn->mask[3]|= mask;
break;
}
#endif
if(apn->next==0) apn->next= addpseA();
apn= apn->next;
}
} /* end of insertObject(RE_APixstrExt*, int, int, int, int) */
/* ------------------------------------------------------------------------- */
void insertFlatObject(RE_APixstrExt *apn, int obindex, int obtype, int dist, int mask)
{
while(apn) {
if(apn->t[0] == RE_NONE) {
apn->p[0] = obindex; apn->zmin[0] = dist;
apn->zmax[0] = dist; apn->mask[0] = mask;
apn->t[0] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[0] & obtype) && (apn->p[0] == obindex)) {
apn->mask[0]|= mask; break;
}
#endif
if(apn->t[1] == RE_NONE) {
apn->p[1] = obindex; apn->zmin[1] = dist;
apn->zmax[1] = dist; apn->mask[1] = mask;
apn->t[1] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[1] & obtype) && (apn->p[1] == obindex)) {
apn->mask[1]|= mask; break;
}
#endif
if(apn->t[2] == RE_NONE) {
apn->p[2] = obindex; apn->zmin[2] = dist;
apn->zmax[2] = dist; apn->mask[2] = mask;
apn->t[2] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[2] & obtype) && (apn->p[2] == obindex)) {
apn->mask[2]|= mask; break;
}
#endif
if(apn->t[3] == RE_NONE) {
apn->p[3] = obindex; apn->zmin[3] = dist;
apn->zmax[3] = dist; apn->mask[3] = mask;
apn->t[3] = obtype;
break;
}
#ifndef RE_INDIVIDUAL_SUBPIXELS
if( (apn->t[3] & obtype) && (apn->p[3] == obindex)) {
apn->mask[3]|= mask; break;
}
#endif
if(apn->next==0) apn->next= addpseA();
apn= apn->next;
};
} /* end of void insertFlatObject(RE_APixstrExt, int, int, int, int)*/
/* ------------------------------------------------------------------------- */
/* This function might be helped by an end-of-list marker */
void insertFlatObjectNoOsa(RE_APixstrExt *ap,
int obindex,
int obtype,
int dist,
int mask)
{
while(ap) {
if(ap->t[0] == RE_NONE) {
ap->p[0] = obindex; ap->zmin[0] = dist;
ap->zmax[0] = dist; ap->mask[0] = mask;
ap->t[0] = obtype;
break;
}
if(ap->t[1] == RE_NONE) {
ap->p[1] = obindex; ap->zmin[1] = dist;
ap->zmax[1] = dist; ap->mask[1] = mask;
ap->t[1] = obtype;
break;
}
if(ap->t[2] == RE_NONE) {
ap->p[2] = obindex; ap->zmin[2] = dist;
ap->zmax[2] = dist; ap->mask[2] = mask;
ap->t[2] = obtype;
break;
}
if(ap->t[3] == RE_NONE) {
ap->p[3] = obindex; ap->zmin[3] = dist;
ap->zmax[3] = dist; ap->mask[3] = mask;
ap->t[3] = obtype;
break;
}
if(ap->next==0) ap->next= addpseA();
ap= ap->next;
};
} /* end of void insertFlatObjectNoOsa(RE_APixstrExt, int, int, int, int)*/
/* ------------------------------------------------------------------------- */
/* EOF */