1 //////////////////////////////////////////////////////////////////////
2 //
3 //                             Pixie
4 //
5 // Copyright � 1999 - 2003, Okan Arikan
6 //
7 // Contact: okan@cs.utexas.edu
8 //
9 //	This library is free software; you can redistribute it and/or
10 //	modify it under the terms of the GNU Lesser General Public
11 //	License as published by the Free Software Foundation; either
12 //	version 2.1 of the License, or (at your option) any later version.
13 //
14 //	This library is distributed in the hope that it will be useful,
15 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 //	Lesser General Public License for more details.
18 //
19 //	You should have received a copy of the GNU Lesser General Public
20 //	License along with this library; if not, write to the Free Software
21 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 //
23 ///////////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////////
25 //
26 //  File				:	shaderPl.cpp
27 //  Classes				:	CPLLookup
28 //  Description			:	Implementation
29 //
30 ////////////////////////////////////////////////////////////////////////
31 #include <stddef.h>
32 #include "common/algebra.h"
33 #include "common/os.h"
34 #include "attributes.h"
35 #include "shaderPl.h"
36 #include "rendererc.h"
37 #include "bundles.h"
38 #include "error.h"
39 #include "variable.h"
40 #include "renderer.h"
41 #include "shading.h"
42 
43 
44 ///////////////////////////////////////////////////////////////////////
45 // Class				:	CPLLookup
46 // Method				:	CPLLookup
47 // Description			:	Ctor
48 // Return Value			:	-
49 // Comments				:
CPLLookup()50 CPLLookup::CPLLookup() {
51 	numUniforms		=	0;
52 	numVaryings		=	0;
53 	uniforms		=	NULL;
54 	varyings		=	NULL;
55 	instance		=	0;
56 	code			=	0;
57 	next			=	NULL;
58 }
59 
60 ///////////////////////////////////////////////////////////////////////
61 // Class				:	CPLLookup
62 // Method				:	~CPLLookup
63 // Description			:	Dtor
64 // Return Value			:	-
65 // Comments				:
~CPLLookup()66 CPLLookup::~CPLLookup() {
67 	if (uniforms != NULL)	delete [] uniforms;
68 }
69 
70 ///////////////////////////////////////////////////////////////////////
71 // Class				:	CPLLookup
72 // Method				:	bind
73 // Description			:	The default action simply prints an error
74 // Return Value			:	-
75 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)76 void	CPLLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
77 	error(CODE_BADTOKEN,"Unknown parameter: \"%s\" in shader %s\n",name,shader->getName());
78 }
79 
80 ///////////////////////////////////////////////////////////////////////
81 // Class				:	CPLLookup
82 // Method				:	add
83 // Description			:	Add a parameter
84 // Return Value			:	-
85 // Comments				:
add(const char * name,int opIndex,int step,void * data,size_t dest)86 void	CPLLookup::add(const char *name,int opIndex,int step,void *data,size_t dest) {
87 	TParamBinding	*cBinding;
88 
89 	if (data != NULL)	cBinding	=	uniforms + numUniforms++;
90 	else				cBinding	=	varyings + numVaryings++;
91 
92 	cBinding->name		=	name;
93 	cBinding->opIndex	=	opIndex;
94 	cBinding->step		=	step;
95 	cBinding->dest		=	dest;
96 }
97 
98 
99 
100 
101 #define	expectUniform(__name)	if (data == NULL)	warning(CODE_CONSISTENCY,"\"%s\" parameter was expected to be uniform\n",__name)
102 
103 
104 
105 
106 
107 
108 
109 ///////////////////////////////////////////////////////////////////////
110 // Class				:	CTextureLookup
111 // Method				:	CTextureLookup
112 // Description			:	Ctor
113 // Return Value			:	-
114 // Comments				:
CTextureLookup()115 CTextureLookup::CTextureLookup() {
116 	map		=	NULL;
117 	filter	=	RiBoxFilter;
118 }
119 
120 ///////////////////////////////////////////////////////////////////////
121 // Class				:	CTextureLookup
122 // Method				:	~CTextureLookup
123 // Description			:	Dtor
124 // Return Value			:	-
125 // Comments				:
~CTextureLookup()126 CTextureLookup::~CTextureLookup() {
127 }
128 
129 
130 ///////////////////////////////////////////////////////////////////////
131 // Class				:	CTextureLookup
132 // Method				:	bind
133 // Description			:	Bind a texture lookup parameter
134 // Return Value			:	-
135 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)136 void		CTextureLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
137 
138 	// Find the parameter and bind it
139 	if (strcmp(name,"filter") == 0) {
140 		expectUniform(name);
141 		else				filter		=	CRenderer::getFilter(((const char **) data)[0]);
142 	} else if (strcmp(name,"blur") == 0) {
143 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.blur));
144 	} else if (strcmp(name,"width") == 0) {
145 		expectUniform(name);
146 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.width));
147 	} else if (strcmp(name,"swidth") == 0) {
148 		expectUniform(name);
149 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.swidth));
150 	} else if (strcmp(name,"twidth") == 0) {
151 		expectUniform(name);
152 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.twidth));
153 	} else if (strcmp(name,"fill") == 0) {
154 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.fill));
155 	} else if (strcmp(name,"samples") == 0) {
156 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.samples));
157 	} else	CPLLookup::bind(name,opIndex,step,data,shader);
158 }
159 
160 
161 ///////////////////////////////////////////////////////////////////////
162 // Class				:	CTextureLookup
163 // Method				:	init
164 // Description			:	Initialize the scratch for this lookup
165 // Return Value			:	-
166 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)167 void		CTextureLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
168 	scratch->textureParams.filter	=	filter;
169 	scratch->textureParams.blur		=	0;
170 	scratch->textureParams.width	=	1;
171 	scratch->textureParams.swidth	=	1;
172 	scratch->textureParams.twidth	=	1;
173 	scratch->textureParams.fill		=	0;
174 	scratch->textureParams.samples	=	1;
175 }
176 
177 ///////////////////////////////////////////////////////////////////////
178 // Class				:	CTextureLookup
179 // Method				:	init
180 // Description			:	Initialize texture lookup scratch for null lookup
181 // Return Value			:	-
182 // Comments				:	used by irradiance cache
staticInit(CShadingScratch * scratch)183 void CTextureLookup::staticInit(CShadingScratch *scratch) {
184 	scratch->textureParams.filter	=	RiBoxFilter;
185 	scratch->textureParams.blur		=	0;
186 	scratch->textureParams.width	=	1;
187 	scratch->textureParams.swidth	=	1;
188 	scratch->textureParams.twidth	=	1;
189 	scratch->textureParams.fill		=	0;
190 	scratch->textureParams.samples	=	1;
191 }
192 
193 ///////////////////////////////////////////////////////////////////////
194 // Class				:	CTraceLookup
195 // Method				:	CTraceLookup
196 // Description			:	Ctor
197 // Return Value			:	-
198 // Comments				:
CTraceLookup()199 CTraceLookup::CTraceLookup() {
200 }
201 
202 ///////////////////////////////////////////////////////////////////////
203 // Class				:	CTraceLookup
204 // Method				:	~CTraceLookup
205 // Description			:	Dtor
206 // Return Value			:	-
207 // Comments				:
~CTraceLookup()208 CTraceLookup::~CTraceLookup() {
209 }
210 
211 
212 ///////////////////////////////////////////////////////////////////////
213 // Class				:	CTransmissionLookup
214 // Method				:	bind
215 // Description			:	Bind an environment lookup parameter
216 // Return Value			:	-
217 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)218 void		CTraceLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
219 
220 	// Find the parameter and bind it
221 	if (strcmp(name,"samples") == 0) {
222 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.samples));
223 	} else if (strcmp(name,"bias") == 0) {
224 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.bias));
225 	} else if (strcmp(name,"samplecone") == 0) {
226 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.coneAngle));
227 	} else if (strcmp(name,"sampleBase") == 0) {
228 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.sampleBase));
229 	} else if (strcmp(name,"maxdist") == 0) {
230 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.maxDist));
231 	} else if (strcmp(name,"label") == 0) {
232 		expectUniform(name);
233 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.label));
234 	} else	CPLLookup::bind(name,opIndex,step,data,shader);
235 }
236 
237 
238 ///////////////////////////////////////////////////////////////////////
239 // Class				:	CTransmissionLookup
240 // Method				:	init
241 // Description			:	Initialize the scratch for this lookup
242 // Return Value			:	-
243 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)244 void		CTraceLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
245 
246 	scratch->traceParams.samples	=	1;
247 	scratch->traceParams.bias		=	attributes->bias;
248 	scratch->traceParams.coneAngle	=	0;
249 	scratch->traceParams.sampleBase =	1;
250 	scratch->traceParams.maxDist	=	C_INFINITY;
251 	scratch->traceParams.label		=	"";
252 }
253 
254 
255 
256 
257 
258 
259 ///////////////////////////////////////////////////////////////////////
260 // Class				:	CEnvironmentLookup
261 // Method				:	CEnvironmentLookup
262 // Description			:	Ctor
263 // Return Value			:	-
264 // Comments				:
CEnvironmentLookup()265 CEnvironmentLookup::CEnvironmentLookup() {
266 	filter	=	RiBoxFilter;
267 	map		=	NULL;
268 }
269 
270 ///////////////////////////////////////////////////////////////////////
271 // Class				:	CEnvironmentLookup
272 // Method				:	~CEnvironmentLookup
273 // Description			:	Dtor
274 // Return Value			:	-
275 // Comments				:
~CEnvironmentLookup()276 CEnvironmentLookup::~CEnvironmentLookup() {
277 }
278 
279 
280 ///////////////////////////////////////////////////////////////////////
281 // Class				:	CEnvironmentLookup
282 // Method				:	bind
283 // Description			:	Bind an environment lookup parameter
284 // Return Value			:	-
285 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)286 void		CEnvironmentLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
287 
288 	// Find the parameter and bind it
289 	if (strcmp(name,"filter") == 0) {
290 		expectUniform(name);
291 		else	filter		=	CRenderer::getFilter(((const char **) data)[0]);
292 	} else if (strcmp(name,"blur") == 0) {
293 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.blur));
294 	} else if (strcmp(name,"width") == 0) {
295 		expectUniform(name);
296 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.width));
297 	} else if (strcmp(name,"swidth") == 0) {
298 		expectUniform(name);
299 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.swidth));
300 	} else if (strcmp(name,"twidth") == 0) {
301 		expectUniform(name);
302 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.twidth));
303 	} else if (strcmp(name,"fill") == 0) {
304 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.fill));
305 	} else CTraceLookup::bind(name,opIndex,step,data,shader);
306 }
307 
308 ///////////////////////////////////////////////////////////////////////
309 // Class				:	CEnvironmentLookup
310 // Method				:	init
311 // Description			:	Initialize the scratch for this lookup
312 // Return Value			:	-
313 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)314 void		CEnvironmentLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
315 	scratch->textureParams.filter	=	filter;
316 	scratch->textureParams.samples	=	1;	// also filled in where it's used
317 	scratch->textureParams.blur		=	0;
318 	scratch->textureParams.width	=	1;
319 	scratch->textureParams.swidth	=	1;
320 	scratch->textureParams.twidth	=	1;
321 	scratch->textureParams.fill		=	0;
322 	CTraceLookup::init(scratch,attributes);
323 }
324 
325 
326 
327 
328 
329 
330 
331 
332 
333 
334 
335 ///////////////////////////////////////////////////////////////////////
336 // Class				:	CPhotonMapLookup
337 // Method				:	CPhotonMapLookup
338 // Description			:	Ctor
339 // Return Value			:	-
340 // Comments				:
CPhotonMapLookup()341 CPhotonMapLookup::CPhotonMapLookup() {
342 	map	=	NULL;
343 }
344 
345 ///////////////////////////////////////////////////////////////////////
346 // Class				:	CPhotonMapLookup
347 // Method				:	~CPhotonMapLookup
348 // Description			:	Dtor
349 // Return Value			:	-
350 // Comments				:
~CPhotonMapLookup()351 CPhotonMapLookup::~CPhotonMapLookup() {
352 }
353 
354 
355 ///////////////////////////////////////////////////////////////////////
356 // Class				:	CPhotonMapLookup
357 // Method				:	bind
358 // Description			:	Bind an environment lookup parameter
359 // Return Value			:	-
360 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)361 void		CPhotonMapLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
362 
363 	// Find the parameter and bind it
364 	if (strcmp(name,"lookuptype") == 0) {
365 		const char	*type	=	((const char **) data)[0];
366 		if (strcmp(type,"irradiance") != 0) {
367 			error(CODE_BADTOKEN,"Photonmap lookup type \"%s\" is not supported in shader %s\n",type,shader->getName());
368 		}
369 	} else if (strcmp(name,"estimator") == 0) {
370 		expectUniform(name);
371 		add(name,opIndex,step,data,offsetof(CShadingScratch,photonmapParams.estimator));
372 	} else	CPLLookup::bind(name,opIndex,step,data,shader);
373 }
374 
375 ///////////////////////////////////////////////////////////////////////
376 // Class				:	CPhotonMapLookup
377 // Method				:	init
378 // Description			:	Initialize the scratch for this lookup
379 // Return Value			:	-
380 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)381 void		CPhotonMapLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
382 	scratch->photonmapParams.estimator		= 0;
383 }
384 
385 
386 
387 
388 ///////////////////////////////////////////////////////////////////////
389 // Class				:	CMapInfoLookup
390 // Method				:	CMapInfoLookup
391 // Description			:	Ctor
392 // Return Value			:	-
393 // Comments				:
CMapInfoLookup()394 CMapInfoLookup::CMapInfoLookup() {
395 	map	=	NULL;
396 }
397 
398 ///////////////////////////////////////////////////////////////////////
399 // Class				:	CMapInfoLookup
400 // Method				:	~CMapInfoLookup
401 // Description			:	Dtor
402 // Return Value			:	-
403 // Comments				:
~CMapInfoLookup()404 CMapInfoLookup::~CMapInfoLookup() {
405 }
406 
407 
408 
409 
410 
411 ///////////////////////////////////////////////////////////////////////
412 // Class				:	CTexture3dLookup
413 // Method				:	CTexture3dLookup
414 // Description			:	Ctor
415 // Return Value			:	-
416 // Comments				:
CTexture3dLookup()417 CTexture3dLookup::CTexture3dLookup() {
418 	map				=	NULL;
419 	numChannels		=	0;
420 }
421 
422 ///////////////////////////////////////////////////////////////////////
423 // Class				:	CTexture3dLookup
424 // Method				:	~CTexture3dLookup
425 // Description			:	Dtor
426 // Return Value			:	-
427 // Comments				:
~CTexture3dLookup()428 CTexture3dLookup::~CTexture3dLookup() {
429 }
430 
431 
432 ///////////////////////////////////////////////////////////////////////
433 // Class				:	CTexture3dLookup
434 // Method				:	bind
435 // Description			:	Bind the texture3d/bake3d parameters
436 // Return Value			:	-
437 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)438 void		CTexture3dLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
439 
440 	// Find the parameter and bind it
441 	if (strcmp(name,"coordsystem") == 0) {
442 		expectUniform(name);
443 		add(name,opIndex,step,data,offsetof(CShadingScratch,texture3dParams.coordsys));
444 	} else if (strcmp(name,"interpolate") == 0) {
445 		expectUniform(name);
446 		add(name,opIndex,step,data,offsetof(CShadingScratch,texture3dParams.interpolate));
447 	} else if (strcmp(name,"radius") == 0) {
448 		add(name,opIndex,step,data,offsetof(CShadingScratch,texture3dParams.radius));
449 	} else if (strcmp(name,"radiusscale") == 0) {
450 		add(name,opIndex,step,data,offsetof(CShadingScratch,texture3dParams.radiusScale));
451 	} else {
452 		if (data == NULL) {
453 			// The data has to be varying
454 
455 			channelIndex[numChannels]	= opIndex;
456 			channelSize[numChannels]	= step;
457 			channelName[numChannels]	= name;
458 			numChannels++;
459 		} else {
460 			warning(CODE_BADTOKEN,"warning, uniform texture3d parameter \"%s\" ignored\n",name);
461 		}
462 	}
463 }
464 
465 ///////////////////////////////////////////////////////////////////////
466 // Class				:	CTexture3dLookup
467 // Method				:	init
468 // Description			:	Initialize the scratch for this lookup
469 // Return Value			:	-
470 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)471 void		CTexture3dLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
472 	scratch->texture3dParams.coordsys		=	"";
473 	scratch->texture3dParams.interpolate	=	0;
474 	scratch->texture3dParams.radius			=	0;
475 	scratch->texture3dParams.radiusScale	=	1;
476 }
477 
478 ///////////////////////////////////////////////////////////////////////
479 // Class				:	COcclusionLookup
480 // Method				:	init
481 // Description			:	Initialize the scratch for this lookup
482 // Return Value			:	-
483 // Comments				:
postBind(CShadingScratch * scratch)484 void		CTexture3dLookup::postBind(CShadingScratch *scratch) {
485 	if (scratch->texture3dParams.coordsys[0] == '\0') {
486 		scratch->texture3dParams.coordsys = "world";
487 	}
488 }
489 
490 
491 
492 
493 ///////////////////////////////////////////////////////////////////////
494 // Class				:	COcclusionLookup
495 // Method				:	COcclusionLookup
496 // Description			:	Ctor
497 // Return Value			:	-
498 // Comments				:
COcclusionLookup()499 COcclusionLookup::COcclusionLookup() {
500 	environment		=	NULL;
501 	pointHierarchy	=	NULL;
502 }
503 
504 ///////////////////////////////////////////////////////////////////////
505 // Class				:	COcclusionLookup
506 // Method				:	~COcclusionLookup
507 // Description			:	Dtor
508 // Return Value			:	-
509 // Comments				:
~COcclusionLookup()510 COcclusionLookup::~COcclusionLookup() {
511 }
512 
513 
514 ///////////////////////////////////////////////////////////////////////
515 // Class				:	COcclusionLookup
516 // Method				:	bind
517 // Description			:	Bind the indirectdiffuse/occlusion parameters
518 // Return Value			:	-
519 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)520 void		COcclusionLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
521 
522 	// Find the parameter and bind it
523 	if (strcmp(name,"coordsystem") == 0) {
524 		expectUniform(name);
525 		add(name,opIndex,step,data,offsetof(CShadingScratch,texture3dParams.coordsys));
526 	} else if (strcmp(name,"maxdist") == 0) {
527 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.maxDist));
528 	} else if (strcmp(name,"coneangle") == 0) {
529 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.coneAngle));
530 	} else if (strcmp(name,"samplebase") == 0) {
531 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.sampleBase));
532 	} else if (strcmp(name,"label") == 0) {
533 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.label));
534 	} else if (strcmp(name,"bias") == 0) {
535 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.bias));
536 	} else if (strcmp(name,"maxerror") == 0) {
537 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.maxError));
538 	} else if (strcmp(name,"pointbased") == 0) {
539 		expectUniform(name);
540 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.pointbased));
541 	} else if (strcmp(name,"environmentmap") == 0) {
542 		expectUniform(name);
543 		// This is a uniform parameter
544 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.environmentMapName));
545 	} else if (strcmp(name,"filename") == 0) {
546 		expectUniform(name);
547 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.pointHierarchyName));
548 	} else if (strcmp(name,"maxpixeldist") == 0) {
549 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.maxPixelDist));
550 	} else if (strcmp(name,"maxsolidangle") == 0) {
551 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.maxSolidAngle));
552 	} else if (strcmp(name,"environmentcolor") == 0) {
553 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.environmentColor));
554 	} else if (strcmp(name,"maxBrightness") == 0) {
555 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.maxBrightness));
556 	} else if (strcmp(name,"handle") == 0) {
557 		expectUniform(name);
558 		// This is a uniform parameter
559 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.cacheHandle));
560 	} else if (strcmp(name,"filemode") == 0) {
561 		expectUniform(name);
562 		// This is a uniform parameter
563 		add(name,opIndex,step,data,offsetof(CShadingScratch,occlusionParams.cacheMode));
564 	} else {
565 		if (data == NULL) {
566 			// The data has to be varying
567 
568 			channelIndex[numChannels]	= opIndex;
569 			channelSize[numChannels]	= step;
570 			channelName[numChannels]	= name;
571 			numChannels++;
572 		} else {
573 			warning(CODE_BADTOKEN,"Warning, uniform occlusion / indirectdiffuse parameter \"%s\" ignored\n",name);
574 		}
575 	}
576 }
577 
578 ///////////////////////////////////////////////////////////////////////
579 // Class				:	COcclusionLookup
580 // Method				:	init
581 // Description			:	Initialize the scratch for this lookup
582 // Return Value			:	-
583 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)584 void		COcclusionLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
585 	scratch->occlusionParams.environmentMapName	=	NULL;					// None by default
586 	scratch->texture3dParams.coordsys			=	"";
587 	scratch->occlusionParams.maxError			=	attributes->irradianceMaxError;
588 	scratch->occlusionParams.pointbased			=	0;						// This is not a point based lookup
589 	scratch->occlusionParams.maxBrightness		=	1.0f;					// Upper limit on the maximum brightness
590 	scratch->occlusionParams.environmentMapName	=	NULL;					// No environment map by default
591 	scratch->occlusionParams.pointHierarchyName	=	NULL;					// No point hierarchy
592 	scratch->occlusionParams.maxPixelDist		=	attributes->irradianceMaxPixelDistance;		// The maximum distance between samples
593 	scratch->occlusionParams.maxSolidAngle		=	0.05f;					// The maximum solid angle
594 	scratch->occlusionParams.occlusion			=	FALSE;					// Overwritten on the fly
595 	initv(scratch->occlusionParams.environmentColor,0);						// The background color for irradiance
596 	scratch->occlusionParams.pointHierarchy		=	NULL;					// Overwritten on the fly
597 	scratch->occlusionParams.environment		=	NULL;					// Overwritten on the fly
598 	scratch->occlusionParams.cacheHandle		=	attributes->irradianceHandle;				// Use the attribute by default
599 	scratch->occlusionParams.cacheMode			=	attributes->irradianceHandleMode;			// Use the attribute by default
600 
601 	scratch->traceParams.samples				=	1;
602 	scratch->traceParams.maxDist				=	C_INFINITY;
603 	scratch->traceParams.coneAngle				=	0;
604 	scratch->traceParams.sampleBase				=	1;
605 	scratch->traceParams.label					=	"";
606 	scratch->traceParams.bias					=	attributes->bias;
607 
608 }
609 
610 ///////////////////////////////////////////////////////////////////////
611 // Class				:	COcclusionLookup
612 // Method				:	init
613 // Description			:	Initialize the scratch for this lookup
614 // Return Value			:	-
615 // Comments				:
postBind(CShadingScratch * scratch)616 void		COcclusionLookup::postBind(CShadingScratch *scratch) {
617 	if (scratch->texture3dParams.coordsys[0] == '\0') {
618 		scratch->texture3dParams.coordsys = "world";
619 	}
620 }
621 
622 
623 ///////////////////////////////////////////////////////////////////////
624 // Class				:	CFilterLookup
625 // Method				:	CFilterLookup
626 // Description			:	Ctor
627 // Return Value			:	-
628 // Comments				:
CFilterLookup()629 CFilterLookup::CFilterLookup() {
630 	filter		=	RiCatmullRomStepFilter;
631 }
632 
633 ///////////////////////////////////////////////////////////////////////
634 // Class				:	CFilterLookup
635 // Method				:	~CFilterLookup
636 // Description			:	Dtor
637 // Return Value			:	-
638 // Comments				:
~CFilterLookup()639 CFilterLookup::~CFilterLookup() {
640 }
641 
642 ///////////////////////////////////////////////////////////////////////
643 // Class				:	CFilterLookup
644 // Method				:	bind
645 // Description			:	Bind the filterstep parameters
646 // Return Value			:	-
647 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)648 void		CFilterLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
649 
650 	// Find the parameter and bind it
651 	if (strcmp(name,"filter") == 0) {
652 		expectUniform(name);
653 		else				filter		=	CRenderer::getStepFilter(((const char **) data)[0]);
654 	} else if (strcmp(name,"width") == 0) {
655 		expectUniform(name);
656 		add(name,opIndex,step,data,offsetof(CShadingScratch,textureParams.width));
657 	} else	CPLLookup::bind(name,opIndex,step,data,shader);
658 }
659 
660 ///////////////////////////////////////////////////////////////////////
661 // Class				:	CFilterLookup
662 // Method				:	init
663 // Description			:	Initialize the scratch for this lookup
664 // Return Value			:	-
665 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)666 void		CFilterLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
667 	scratch->textureParams.width		=	1.0f;
668 }
669 
670 
671 
672 
673 
674 
675 
676 
677 
678 
679 ///////////////////////////////////////////////////////////////////////
680 // Class				:	CShaderVectorVariable
681 // Description			:	Encapsulates a shader variable
682 // Comments				:
683 class	CShaderVectorVariable : public CGatherVariable {
684 public:
685 
record(float * dest,int nr,CGatherRay ** r,float ** varying)686 			void	record(float *dest,int nr,CGatherRay **r,float **varying) {
687 						const float	*src	=	varying[entry];
688 
689 						for (int i=nr;i>0;--i,src+=3) {
690 							const CGatherRay	*ray	=	(CGatherRay *) (*r++);
691 							movvv(dest + ray->index*3,src);
692 						}
693 					}
694 
695 			int		entry;		// Variable index
696 };
697 
698 ///////////////////////////////////////////////////////////////////////
699 // Class				:	CShaderFloatVariable
700 // Description			:	Encapsulates a shader variable
701 // Comments				:
702 class	CShaderFloatVariable : public CGatherVariable {
703 public:
704 
record(float * dest,int nr,CGatherRay ** r,float ** varying)705 			void	record(float *dest,int nr,CGatherRay **r,float **varying) {
706 						const float	*src	=	varying[entry];
707 
708 						for (int i=nr;i>0;--i) {
709 							const CGatherRay	*ray	=	(CGatherRay *) (*r++);
710 
711 							dest[ray->index]	=	*src++;
712 						}
713 					}
714 
715 			int		entry;		// Variable index
716 };
717 
718 ///////////////////////////////////////////////////////////////////////
719 // Class				:	CRayOriginVariable
720 // Description			:	Ray origin variable
721 // Comments				:
722 class	CRayOriginVariable : public CGatherVariable {
723 public:
724 
record(float * dest,int nr,CGatherRay ** r,float ** varying)725 			void	record(float *dest,int nr,CGatherRay **r,float **varying) {
726 
727 						for (int i=nr;i>0;--i) {
728 							const CGatherRay	*ray	=	(CGatherRay *) (*r++);
729 
730 							movvv(dest + ray->index*3,ray->from);
731 						}
732 					}
733 };
734 
735 ///////////////////////////////////////////////////////////////////////
736 // Class				:	CRayDirVariable
737 // Description			:	Ray direction variable
738 // Comments				:
739 class	CRayDirVariable : public CGatherVariable {
740 public:
741 
record(float * dest,int nr,CGatherRay ** r,float ** varying)742 			void	record(float *dest,int nr,CGatherRay **r,float **varying) {
743 
744 						for (int i=nr;i>0;--i) {
745 							const CGatherRay	*ray	=	(CGatherRay *) (*r++);
746 
747 							movvv(dest + ray->index*3,ray->dir);
748 						}
749 					}
750 };
751 
752 ///////////////////////////////////////////////////////////////////////
753 // Class				:	CRayLengthVariable
754 // Description			:	Ray length variable
755 // Comments				:
756 class	CRayLengthVariable : public CGatherVariable {
757 public:
758 
record(float * dest,int nr,CGatherRay ** r,float ** varying)759 			void	record(float *dest,int nr,CGatherRay **r,float **varying) {
760 
761 						for (int i=nr;i>0;--i) {
762 							const CGatherRay	*ray	=	(CGatherRay *) (*r++);
763 
764 							dest[ray->index]	=	ray->t;
765 						}
766 					}
767 };
768 
769 
770 ///////////////////////////////////////////////////////////////////////
771 // Class				:	CGatherLookup
772 // Method				:	CGatherLookup
773 // Description			:	Ctor
774 // Return Value			:	-
775 // Comments				:
CGatherLookup()776 CGatherLookup::CGatherLookup() {
777 	outputs				=	NULL;
778 	numOutputs			=	0;
779 	nonShadeOutputs		=	NULL;
780 	numNonShadeOutputs	=	0;
781 }
782 
783 ///////////////////////////////////////////////////////////////////////
784 // Class				:	CGatherLookup
785 // Method				:	~CGatherLookup
786 // Description			:	Dtor
787 // Return Value			:	-
788 // Comments				:
~CGatherLookup()789 CGatherLookup::~CGatherLookup() {
790 	CGatherVariable	*cVar;
791 
792 	while((cVar=outputs) != NULL) {
793 		outputs	=	cVar->next;
794 		delete cVar;
795 	}
796 
797 	while((cVar=nonShadeOutputs) != NULL) {
798 		nonShadeOutputs	=	cVar->next;
799 		delete cVar;
800 	}
801 }
802 
803 
804 ///////////////////////////////////////////////////////////////////////
805 // Class				:	CGatherLookup
806 // Method				:	addOutput
807 // Description			:	Adds an output
808 // Return Value			:	-
809 // Comments				:
addOutput(const char * output,int destIndex,CShaderInstance * shader)810 void	CGatherLookup::addOutput(const char *output,int destIndex,CShaderInstance *shader) {
811 	CGatherVariable	*nVar	=	NULL;
812 
813 	if (strncmp(output,"surface:",8) == 0) {
814 		CVariable				*var	=	CRenderer::retrieveVariable(output+8);
815 		if (var == NULL)							error(CODE_BADTOKEN,"Variable \"%s\" is not found in shader %s\n",output,shader->getName());
816 		else if (var->storage != STORAGE_GLOBAL)	error(CODE_BADTOKEN,"Variable \"%s\" is not found in shader %s\n",output,shader->getName());
817 		else {
818 			if (	(var->type == TYPE_VECTOR)	||
819 					(var->type == TYPE_POINT)	||
820 					(var->type == TYPE_COLOR)	||
821 					(var->type == TYPE_NORMAL)) {
822 				CShaderVectorVariable	*outVar	=	new CShaderVectorVariable;
823 				outVar->shade		=	TRUE;
824 				outVar->entry		=	var->entry;
825 				outVar->destIndex	=	destIndex;
826 				outVar->next		=	outputs;
827 				outputs				=	outVar;
828 				numOutputs++;
829 				nVar				=	outVar;
830 			} else if (var->type == TYPE_FLOAT) {
831 				CShaderFloatVariable	*outVar	=	new CShaderFloatVariable;
832 				outVar->shade		=	TRUE;
833 				outVar->entry		=	var->entry;
834 				outVar->destIndex	=	destIndex;
835 				outVar->next		=	outputs;
836 				outputs				=	outVar;
837 				numOutputs++;
838 				nVar				=	outVar;
839 			} else {
840 				error(CODE_BADTOKEN,"Unknown output variable type for gather in shader %s\n",shader->getName());
841 			}
842 		}
843 	} else if (strcmp(output,"ray:origin") == 0) {
844 		CRayOriginVariable	*outVar	=	new CRayOriginVariable;
845 		outVar->destIndex	=	destIndex;
846 		outVar->next		=	nonShadeOutputs;
847 		nonShadeOutputs		=	outVar;
848 		numNonShadeOutputs++;
849 		nVar				=	outVar;
850 	} else if (strcmp(output,"ray:direction") == 0) {
851 		CRayDirVariable	*outVar	=	new CRayDirVariable;
852 		outVar->destIndex	=	destIndex;
853 		outVar->next		=	nonShadeOutputs;
854 		nonShadeOutputs		=	outVar;
855 		numNonShadeOutputs++;
856 		nVar				=	outVar;
857 	} else if (strcmp(output,"ray:length") == 0) {
858 		CRayLengthVariable	*outVar	=	new CRayLengthVariable;
859 		outVar->destIndex	=	destIndex;
860 		outVar->next		=	nonShadeOutputs;
861 		nonShadeOutputs		=	outVar;
862 		numNonShadeOutputs++;
863 		nVar				=	outVar;
864 	} else {
865 		error(CODE_BADTOKEN,"Unknown output variable for gather in shader %s\n",shader->getName());
866 	}
867 }
868 
869 ///////////////////////////////////////////////////////////////////////
870 // Class				:	CGatherLookup
871 // Method				:	bind
872 // Description			:	Bind variables
873 // Return Value			:	-
874 // Comments				:
bind(const char * name,int & opIndex,int step,void * data,CShaderInstance * shader)875 void	CGatherLookup::bind(const char *name,int &opIndex,int step,void *data,CShaderInstance *shader) {
876 	// Find the parameter and bind it
877 	if (strcmp(name,"bias") == 0) {
878 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.bias));
879 	} else if (strcmp(name,"maxdist") == 0) {
880 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.maxDist));
881 	} else if (strcmp(name,"samplebase") == 0) {
882 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.sampleBase));
883 	} else if (strcmp(name,"distribution") == 0) {
884 		expectUniform(name);
885 		add(name,opIndex,step,data,offsetof(CShadingScratch,gatherParams.distribution));
886 	} else if (strcmp(name,"label") == 0) {
887 		expectUniform(name);
888 		add(name,opIndex,step,data,offsetof(CShadingScratch,traceParams.label));
889 	} else {
890 		addOutput(name,opIndex,shader);
891 	}
892 }
893 
894 ///////////////////////////////////////////////////////////////////////
895 // Class				:	CGatherLookup
896 // Method				:	init
897 // Description			:	Init the gather parameters
898 // Return Value			:	-
899 // Comments				:
init(CShadingScratch * scratch,const CAttributes * attributes)900 void	CGatherLookup::init(CShadingScratch *scratch,const CAttributes *attributes) {
901 	scratch->traceParams.samples		=	1;
902 	scratch->traceParams.bias			=	attributes->bias;
903 	scratch->gatherParams.distribution	=	NULL;
904 	scratch->traceParams.sampleBase		=	1;
905 	scratch->traceParams.maxDist		=	C_INFINITY;
906 	scratch->traceParams.label			=	rayLabelGather;
907 }
908