[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12211] branches/soc-2007-joeedh/source/ blender/render/intern/source: Split most of the DSM code from zbuf. c into new file dsm.c.

Joseph Eagar joeedh at gmail.com
Sat Oct 6 20:03:37 CEST 2007


Revision: 12211
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12211
Author:   joeedh
Date:     2007-10-06 20:03:37 +0200 (Sat, 06 Oct 2007)

Log Message:
-----------
Split most of the DSM code from zbuf.c into new file dsm.c.

Modified Paths:
--------------
    branches/soc-2007-joeedh/source/blender/render/intern/source/zbuf.c

Added Paths:
-----------
    branches/soc-2007-joeedh/source/blender/render/intern/source/dsm.c

Added: branches/soc-2007-joeedh/source/blender/render/intern/source/dsm.c
===================================================================
--- branches/soc-2007-joeedh/source/blender/render/intern/source/dsm.c	                        (rev 0)
+++ branches/soc-2007-joeedh/source/blender/render/intern/source/dsm.c	2007-10-06 18:03:37 UTC (rev 12211)
@@ -0,0 +1,1043 @@
+/**
+ * $Id: dsm.c 12209 2007-10-04 21:41:36Z joeedh $
+ *
+ * ***** BEGIN GPL 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.
+ *
+ * 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) 2007 by the Blender Foundation.
+ * All rights reserved.  Copyright is specifically transferred to
+ * the blender foundation by Joseph Eagar.
+ *
+ * Contributors: Joseph Eagar
+  *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+#include "BLI_jitter.h"
+#include "BLI_memarena.h"
+
+#include "BKE_tile.h"
+#include "BKE_dsm.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_curve_types.h"
+
+#include "RE_render_ext.h"
+#include "RE_shader_ext.h"
+
+#include "gammaCorrectionTables.h"
+#include "pixelblending.h"
+#include "render_types.h"
+#include "renderpipeline.h"
+#include "renderdatabase.h"
+#include "rendercore.h"
+#include "shadbuf.h"
+#include "shading.h"
+#include "sss.h"
+#include "zbuf.h"
+
+#include "MEM_guardedalloc.h"
+
+static TCS_TilePool *deepbuffer_pool = NULL;
+
+/* prototypes */
+void DSM_DoTile(Render *re, ShadBuf *buf, DSMTile *tile, DSMBuffer *dbuf);
+int zbuffer_dsm(Render *re, RenderPart *pa, APixstr *APixbuf,
+					   ListBase *apsmbase, unsigned int lay, float clipend, 
+					   ShadBuf *buf, ListBase *vlackbucket);
+
+static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco);
+static APixstr *addpsmainA(ListBase *lb);
+static void freepsA(ListBase *lb);
+static APixstr *addpsA(ZSpan *zspan);
+
+void DSM_MakeTilePool(int maxbytes)
+{
+	deepbuffer_pool = TCS_MakePool(maxbytes, "dsm");
+}
+
+void DSM_FreeTilePool(void)
+{
+	if (deepbuffer_pool) TCS_FreePool(deepbuffer_pool);
+	deepbuffer_pool = NULL;
+}
+
+/*doesn't actually free the DSMBuffer struct, only direct data*/
+void DSM_FreeBuffer(DSMBuffer *dbuf)
+{
+	int i;
+
+	printf("freeing!\n");
+
+	for (i=0; i<dbuf->tilex*dbuf->tiley; i++) {
+		//printf("freeing tile arena!\n");
+
+		TCS_FreeTile(&dbuf->vfunc_rect[i]);
+		if (dbuf->vfunc_rect[i].arena) BLI_memarena_free(dbuf->vfunc_rect[i].arena);
+	}
+	MEM_freeN(dbuf->vfunc_rect);
+}
+
+#define FINDMINMAX(minx, miny, maxx, maxy, co) {\
+	if (co[0] < minx) minx = co[0];\
+	if (co[0] > maxx) maxx = co[0];\
+	if (co[1] < miny) miny = co[1];\
+	if (co[1] > maxy) maxy = co[1];}
+
+#define FINDBOUNDS(minx, miny, maxx, maxy, vlr) {\
+	minx = miny = 232634.0f;\
+	maxx = maxy = -2342343.0f;\
+	hoco_to_zco(&span, co, vlr->v1->ho);\
+	FINDMINMAX(minx, miny, maxx, maxy, co)\
+	hoco_to_zco(&span, co, vlr->v2->ho);\
+	FINDMINMAX(minx, miny, maxx, maxy, co)\
+	hoco_to_zco(&span, co, vlr->v3->ho);\
+	FINDMINMAX(minx, miny, maxx, maxy, co)\
+	if (vlr->v4) {\
+			hoco_to_zco(&span, co, vlr->v4->ho);\
+			FINDMINMAX(minx, miny, maxx, maxy, co) } }
+
+void DSM_FreeZbufferBucket(ListBase *bucket)
+{
+	VlakBucket *vbucket, *next;
+
+	for (vbucket=bucket->first; vbucket; vbucket=next) {
+		next = vbucket->next;
+		MEM_freeN(vbucket);
+	}
+}
+
+ListBase *DSM_FillZbufferBuckets(Render *re, int sizex, int sizey, int tsizex, 
+								  int tsizey, int tilex, int tiley, float borderx, float bordery)
+{
+	ListBase *buckets = MEM_callocN(sizeof(ListBase)*tilex*tiley, "zbucket rect");
+	VlakBucket *vlakbp;
+	VlakRen *vlr;
+	int x, y, i;
+	float minx, miny, maxx, maxy, mulx, muly, co[4];
+	ZSpan span;
+
+	memset(&span, 0, sizeof(span));
+	span.hoco_to_zco = NULL;
+	span.zmulx = mulx = ((float)sizex) / 2.0;
+	span.zmuly = muly = ((float)sizey) / 2.0;
+
+	span.zofsx = -0.5;
+	span.zofsy = -0.5;
+
+	for (i=0; i<re->totvlak; i++) {
+		if((i & 255)==0)
+			vlr= re->vlaknodes[i>>8].vlak;
+		else vlr++;
+
+		FINDBOUNDS(minx, miny, maxx, maxy, vlr);
+
+		/*if min[x/y] and max[x/y] are the same,
+		  add 1 to max[x/y] and subtract 1
+		  from min[x/y].  1 is subtracted from min[x/y]
+		  to handle theoretical cases of simply adding 1
+		  to max[x/y] not working*/
+		minx -= borderx;
+		miny -= bordery;
+		maxx += borderx;
+		maxy += bordery;
+		if (maxx == minx) {
+			maxx += 1;
+			minx -= 1;
+		}
+		if (maxy == miny) {
+			maxy += 1;
+			miny -= 1;
+		}
+
+		if (maxx < 0) maxx = 0;
+		if (maxx >= sizex) maxx = sizex-1;
+		if (minx < 0) minx = 0;
+		if (minx >= sizex) minx = sizex-1;
+
+		if (maxy < 0) maxy = 0;
+		if (maxy >= sizey) maxy = sizey-1;
+		if (miny < 0) miny = 0;
+		if (miny >= sizey) miny = sizey-1;
+		
+		minx /= tsizex;
+		miny /= tsizey;
+		maxx /= tsizex;
+		maxy /= tsizey;
+
+		//printf("after conversion, minx: %f, miny: %f, maxx: %f, maxy: %f\n", minx, miny, maxx, maxy);
+
+		for (x=minx; x<maxx; x++) {
+			for (y=miny; y<maxy; y++) {
+				vlakbp = buckets[y*tilex+x].last;
+				if (!vlakbp || (vlakbp && vlakbp->used == MAX_VLACKBUCKET)) {
+					vlakbp = MEM_mallocN(sizeof(VlakBucket), "VlackBucket");
+					vlakbp->used = 0;
+					BLI_addtail(&buckets[y*tilex+x], vlakbp);
+				}
+
+				vlakbp->nodes[vlakbp->used++] = vlr;
+			}
+		}		
+	}
+
+	return buckets;
+}
+
+void DSM_CreateBuffer(Render *re, ShadBuf *buf, int tilesize)
+{
+	DSMBuffer *dbuf = MEM_mapallocN(sizeof(DSMBuffer), "DSMBuffer");
+	DSMTile *tile;
+	float fac;
+	int x, y;
+
+	if (tilesize > buf->size) tilesize = buf->size;
+
+	TCS_InitBuffer(&TCS_DeepShadowBuffer, dbuf);
+
+	if (deepbuffer_pool == NULL) printf("oh EVVVIL!\n");
+
+	/*use 7500 max elements for the 2 preallocated
+	  pixel arrays DSM_DoTile() allocates.  the *6
+	  iirc is because the visibilty function calculation
+	  kindof expands things (note this is usually more then
+	  compensated by the final visibility function compression).*/
+	dbuf->max_depth = 15500*6;
+
+	dbuf->tsizex = dbuf->tsizey = tilesize;
+	dbuf->sizex = dbuf->sizey = buf->size;
+	dbuf->tilex = dbuf->tiley = buf->size / tilesize;
+	
+	/*add extra tiles if necassary.
+
+	  python tests indicated the + 0.000001 is needed; I have no idea why,
+	  some sort of numerical error I assume.  of course python uses doubles and
+	  not floats, but I rather doubt that floats are going to behave any better.*/
+	fac = ((float)buf->size/(float)tilesize) + 0.0000001;
+
+	if ((int)((fac - (int)fac)*(float)tilesize) > 0.000001) {
+		dbuf->tilex += 1;
+		dbuf->tiley += 1;
+	}
+
+
+	dbuf->buckets = DSM_FillZbufferBuckets(re, dbuf->sizex, dbuf->sizey, 
+								    dbuf->tsizex, dbuf->tsizey, dbuf->tilex, 
+									dbuf->tiley, buf->soft, buf->soft);
+
+	dbuf->vfunc_rect = MEM_mapallocN(sizeof(DSMTile)*dbuf->tilex*dbuf->tiley, "dsm tiles");
+
+	buf->dsmbuffer = dbuf;
+	
+	if (G.rt==44) *((int*)0L) = 0;
+
+	for (y=0; y<dbuf->tiley; y++) {
+		for (x=0; x<dbuf->tilex; x++) {
+			tile = &dbuf->vfunc_rect[y*dbuf->tilex+x];
+
+			/*right and top border tiles arn't always the same size as the others*/
+			if (x == dbuf->tilex-1) tile->sizex = dbuf->sizex - dbuf->tsizex*x; //dbuf->sizex - dbuf->tsizex*(x-1); //tilesize - (tilesize*x - dbuf->sizex);
+			else tile->sizex = dbuf->tsizex;
+
+			if (y == dbuf->tiley-1) tile->sizey = dbuf->sizey - dbuf->tsizey*y;//tilesize - (tilesize*y - dbuf->sizey);
+			else tile->sizey = dbuf->tsizey;
+
+			tile->x = x;
+			tile->y = y;
+
+			tile->arena = BLI_memarena_new(DSM_TILE_MEMARENASIZE); /*FIXMEGREP: tweak this to find optimal value.*/
+			BLI_memarena_use_mapalloc(tile->arena);
+			tile->r_rect = BLI_memarena_alloc(tile->arena, sizeof(void*)*tile->sizex*tile->sizey);
+			tile->g_rect = BLI_memarena_alloc(tile->arena, sizeof(void*)*tile->sizex*tile->sizey);
+			tile->b_rect = BLI_memarena_alloc(tile->arena, sizeof(void*)*tile->sizex*tile->sizey);
+
+			printf("Rendering a dsm shadow tile! Tile %d of %d\n", y*dbuf->tilex+x, dbuf->tilex*dbuf->tiley);
+			DSM_DoTile(re, buf, tile, dbuf);
+			_DSM_maketile((TCS_TileBuffer*)dbuf, deepbuffer_pool, (TCS_Tile*)tile);
+			DSM_FreeZbufferBucket(&dbuf->buckets[tile->y*dbuf->tilex+tile->x]);
+		}
+	}
+
+	/*free vlak bucket rect, we don't need it any more.
+	  the actual vlack buckets were freed in the above loop.*/
+	MEM_freeN(dbuf->buckets);
+}
+
+typedef struct _ClrEntry {
+	struct _ClrEntry *next, *prev;
+	ListBase *srclist;
+	int depth;
+	int p;
+	int ispolygon;
+	int samplenr;
+	float value;
+	int index; /* color component index */
+} _ClrEntry;
+
+/* comparison function for qsort, used in DSM_DoTile to sort pixel samples. */
+static int dsmvergzvlak(const void *a1, const void *a2)
+{
+	const _ClrEntry *x1=a1, *x2=a2;
+
+	if( x1->depth < x2->depth ) return -1;
+	else if( x1->depth > x2->depth) return 1;
+	/*ok they both have the same depth, sort by opacity*/
+	else {
+		if (x1->value < x2->value) return 1;
+		else if (x1->value > x2->value) return -1;
+		else return 0;
+	}
+}
+
+/*
+ This function removes extraneous points
+ from a density function.  It works by
+ casting a triangular "beam" from a vertex,
+ then clipping it with subsequent vertices's
+ opacity - err and opacity + err, until it
+ no longer exists.
+
+ See original Deep Shadow Maps paper for more details.
+*/
+static void DSM_CompressFunction(MemArena *arena, DSMFunction *func, float error)
+{
+	DSMLayerSample *samp = func->samples, *cursamp, *newsamp;
+	/*start and end are slopes*/
+	double start, end, ostartpoint, oendpoint, startpoint = -1, endpoint = -1, err=error/2.0;
+	int totface=0, a=0, olda, count=0;
+	
+	//if (err==0) err = 0.001;
+
+	cursamp = func->samples;
+	
+	if (G.rt == 43) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list