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				:	shader.cpp
27 //  Classes				:	CShader
28 //							CShaderInstance
29 //  Description			:	Implementation
30 //
31 ////////////////////////////////////////////////////////////////////////
32 #include	<math.h>
33 #include	<stdio.h>
34 #include	<string.h>
35 
36 #include	"error.h"
37 #include	"shader.h"
38 #include	"stats.h"
39 #include	"shading.h"
40 #include	"bundles.h"
41 #include	"memory.h"
42 #include	"renderer.h"
43 #include	"attributes.h"
44 #include	"common/align.h"
45 
46 
47 ///////////////////////////////////////////////////////////////////////
48 // Class				:	CShader
49 // Method				:	CShader
50 // Description			:	Constructor
51 // Return Value			:	-
52 // Comments				:
CShader(const char * name)53 CShader::CShader(const char *name) : CFileResource(name) {
54 	atomicIncrement(&stats.numShaders);
55 
56 	name					=	NULL;
57 	memory					=	NULL;
58 	codeArea				=	NULL;
59 	constantEntries			=	NULL;
60 	varyingSizes			=	NULL;
61 	strings					=	NULL;
62 	parameters				=	NULL;
63 	flags					=	0;
64 	data					=	NULL;
65 }
66 
67 ///////////////////////////////////////////////////////////////////////
68 // Class				:	CShader
69 // Method				:	~CShader
70 // Description			:	Dtor
71 // Return Value			:	-
72 // Comments				:
~CShader()73 CShader::~CShader() {
74 	int			i;
75 	CVariable	*cParameter;
76 
77 	atomicDecrement(&stats.numShaders);
78 
79 	// Ditch the parameters
80 	while((cParameter = parameters) != NULL) {
81 		parameters	=	parameters->next;
82 
83 		// Delete the default values
84 		if (cParameter->defaultValue != NULL)	delete [] (float *) cParameter->defaultValue;
85 
86 		// Delete the parameter
87 		delete cParameter;
88 	}
89 
90 	// Delete the strings allocated for this shader
91 	for (i=0;i<numStrings;i++) {
92 		free(strings[i]);
93 	}
94 
95 	// Delete additional data
96 	if (data != NULL)		delete data;
97 
98 	// Ditch the memory baby
99 	if (memory != NULL)					free_untyped(memory);
100 }
101 
102 
103 
104 ///////////////////////////////////////////////////////////////////////
105 // Class				:	CShader
106 // Method				:	analyse
107 // Description			:	work out if there are special parameters
108 // Return Value			:	-
109 // Comments				:
analyse()110 void CShader::analyse() {
111 	CVariable	*cVariable;
112 	int			varIndex	=	numGlobals-1;
113 
114 	// BEWARE that this is reversed compareed to the instance order
115 	// hence the reversed counting of globalIndex
116 	for (cVariable=parameters;cVariable!=NULL;cVariable=cVariable->next) {
117 		// Check for special parameters
118 		if (cVariable->storage == STORAGE_MUTABLEPARAMETER || cVariable->storage == STORAGE_GLOBAL) {
119 			if (type == SL_LIGHTSOURCE) {
120 				if (!strcmp(cVariable->name,"__nondiffuse")) {
121 					if ((cVariable->numItems == 1) && cVariable->type == TYPE_FLOAT) {
122 						flags				|=	 SHADERFLAGS_NONDIFFUSE;
123 
124 						if (data == NULL)	data = new CLightShaderData;
125 						CLightShaderData *lightData = (CLightShaderData*) data;
126 
127 						lightData->nonDiffuseIndex	=	varIndex;
128 						lightData->nonDiffuseStep	=	((cVariable->container == CONTAINER_CONSTANT) || (cVariable->container == CONTAINER_UNIFORM)) ? 0 : 1;
129 					} else {
130 						warning(CODE_BADTOKEN,"warning type mismatch for expected definition of __nondiffuse in shader \"%s\"",name);
131 					}
132 				} else if (!strcmp(cVariable->name,"__nonspecular")) {
133 					if ((cVariable->numItems == 1) && cVariable->type == TYPE_FLOAT) {
134 						flags				|=	 SHADERFLAGS_NONSPECULAR;
135 
136 						if (data == NULL)	data = new CLightShaderData;
137 						CLightShaderData *lightData = (CLightShaderData*) data;
138 
139 						lightData->nonSpecularIndex	=	varIndex;
140 						lightData->nonSpecularStep	=	((cVariable->container == CONTAINER_CONSTANT) || (cVariable->container == CONTAINER_UNIFORM)) ? 0 : 1;
141 					} else {
142 						warning(CODE_BADTOKEN,"warning type mismatch for expected definition of __nonspecular in shader \"%s\"",name);
143 					}
144 				}
145 			}
146 			varIndex--;
147 		}
148 	}
149 
150 	if (usedParameters & PARAMETER_NONAMBIENT)
151 		flags				|=	 SHADERFLAGS_NONAMBIENT;
152 }
153 
154 
155 
156 ///////////////////////////////////////////////////////////////////////
157 // Class				:	CShaderInstance
158 // Method				:	CShaderInstance
159 // Description			:	Ctor
160 // Return Value			:	-
161 // Comments				:
CShaderInstance(CAttributes * a,CXform * x)162 CShaderInstance::CShaderInstance(CAttributes *a,CXform *x) {
163 	atomicIncrement(&stats.numShaderInstances);
164 
165 	attach();
166 
167 	xform		=	x;
168 	xform->attach();
169 
170 	categories	=	NULL;
171 	parameters	=	NULL;	// The children class may want to clone the parent's parameters here
172 }
173 
174 ///////////////////////////////////////////////////////////////////////
175 // Class				:	CShaderInstance
176 // Method				:	CShaderInstance
177 // Description			:	Ctor
178 // Return Value			:	-
179 // Comments				:
~CShaderInstance()180 CShaderInstance::~CShaderInstance() {
181 	atomicDecrement(&stats.numShaderInstances);
182 
183 	xform->detach();
184 
185 	if (categories != NULL)	delete[] categories;
186 
187 	// Note: data is not owned by the instance
188 
189 	// The children class must clear the parameter list here
190 }
191 
192 
193 
194 ///////////////////////////////////////////////////////////////////////
195 // Function				:	getToken
196 // Description			:	This function implements "strsep" which is non portable
197 // Return Value			:
198 // Comments				:
token(char ** str,const char * tok)199 static char	*token(char **str,const char *tok) {
200 	char	*cStr	=	*str;
201 	char	*oStr	=	cStr;
202 	int		n		=	(int) strlen(tok);
203 	int		i;
204 
205 	if (cStr == NULL)	return NULL;
206 
207 	// Walk the string
208 	for (;;) {
209 
210 		// Did we run out of string ?
211 		if (*cStr == '\0') {
212 			*str	=	NULL;
213 			break;
214 		}
215 
216 		// Check for a delimiter
217 		for (i=0;i<n;i++) {
218 			if (*cStr == tok[i]) break;
219 		}
220 
221 		if (i == n)	cStr++;
222 		else {
223 			// Delimiter found, terminate
224 			*cStr	=	'\0';
225 			*str	=	cStr+1;
226 			break;
227 		}
228 	}
229 
230 	return oStr;
231 }
232 
233 ///////////////////////////////////////////////////////////////////////
234 // Class				:	CShaderInstance
235 // Method				:	CShaderInstance
236 // Description			:	Ctor
237 // Return Value			:	-
238 // Comments				:
createCategories()239 void CShaderInstance::createCategories() {
240 	char	*categoryString,*cCat,*tmp;
241 	int		i,numCategories;
242 
243 	if (getParameter("__category",&categoryString,NULL,NULL) == TRUE) {
244 		tmp = categoryString = strdup(categoryString);
245 
246 		numCategories = 2;
247 		while (*tmp!='\0') {
248 			if (*tmp == ',') numCategories++;
249 			tmp++;
250 		}
251 		tmp = categoryString;
252 
253 		categories = new int[numCategories];
254 
255 		i=0;
256 		do {
257 			cCat = token(&tmp,",\t ");
258 			if (*cCat != '\0') categories[i++] = CRenderer::getGlobalID(cCat);
259 		} while (tmp != NULL);
260 		categories[i++] = 0;	// terminate the list
261 
262 		free(categoryString);
263 	}
264 }
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 ///////////////////////////////////////////////////////////////////////
276 // Class				:	CProgrammableShaderInstance
277 // Method				:	CProgrammableShaderInstance
278 // Description			:	Ctor
279 // Return Value			:	-
280 // Comments				:
CProgrammableShaderInstance(CShader * p,CAttributes * a,CXform * x)281 CProgrammableShaderInstance::CProgrammableShaderInstance(CShader *p,CAttributes *a,CXform *x) : CShaderInstance(a,x) {
282 	CVariable	*cVariable;
283 
284 	strings				=	NULL;
285 	parent				=	p;
286 	flags				=	parent->flags;
287 	data				=	parent->data;
288 
289 	// Clone the parent's parameter list
290 	// BEWARE that this reverses the order (which matters when counting the globalIndex)
291 	for (cVariable=parent->parameters;cVariable!=NULL;cVariable=cVariable->next) {
292 		CVariable	*nVariable	=	new CVariable;
293 
294 		*nVariable		=	*cVariable;
295 		nVariable->next	=	parameters;
296 		parameters		=	nVariable;
297 
298 		// Allocate a new default value
299 		if (nVariable->type == TYPE_STRING) {
300 			nVariable->defaultValue	=	new char *[nVariable->numFloats];
301 			memcpy(nVariable->defaultValue,cVariable->defaultValue,nVariable->numFloats*sizeof(char*));
302 		} else {
303 			nVariable->defaultValue	=	new float[nVariable->numFloats];
304 			memcpy(nVariable->defaultValue,cVariable->defaultValue,nVariable->numFloats*sizeof(float));
305 		}
306 	}
307 }
308 
309 ///////////////////////////////////////////////////////////////////////
310 // Class				:	CProgrammableShaderInstance
311 // Method				:	~CProgrammableShaderInstance
312 // Description			:	Dtor
313 // Return Value			:	-
314 // Comments				:
~CProgrammableShaderInstance()315 CProgrammableShaderInstance::~CProgrammableShaderInstance() {
316 	CVariable			*cParameter;
317 	CAllocatedString	*cString;
318 
319 	// Ditch the parameters
320 	while((cParameter = parameters) != NULL) {
321 		parameters	=	parameters->next;
322 
323 		// Delete the default values
324 		if (cParameter->defaultValue != NULL) {
325 			if (cParameter->type == TYPE_STRING)		delete [] (char**) cParameter->defaultValue;
326 			else										delete [] (float*) cParameter->defaultValue;
327 		}
328 
329 		// Delete the parameter
330 		delete cParameter;
331 	}
332 
333 	// Ditch the allocated strings
334 	while((cString = strings) != NULL) {
335 		strings	=	cString->next;
336 
337 		free(cString->string);
338 		delete cString;
339 	}
340 
341 }
342 
343 
344 ///////////////////////////////////////////////////////////////////////
345 // Class				:	CProgrammableShaderInstance
346 // Method				:	setParameters
347 // Description			:	Set the values of the parameters
348 // Return Value			:	-
349 // Comments				:
setParameter(const char * param,const void * val)350 int	CProgrammableShaderInstance::setParameter(const char *param,const void *val) {
351 	CVariable	*cParameter;
352 
353 	for (cParameter=parameters;cParameter!=NULL;cParameter=cParameter->next) {
354 
355 		if (strcmp(param,cParameter->name) == 0) {
356 			switch(cParameter->type) {
357 			case TYPE_FLOAT:
358 				{
359 					const float	*src	=	(const float *) val;
360 					float		*dest	=	(float *)		cParameter->defaultValue;
361 					memcpy(dest,src,cParameter->numItems*sizeof(float));
362 				}
363 				break;
364 			case TYPE_COLOR:
365 				{
366 					int			p;
367 					const float	*src	=	(const float *) val;
368 					float		*dest	=	(float *)		cParameter->defaultValue;
369 
370 					for (p=cParameter->numItems;p>0;p--,dest+=3,src+=3) {
371 						movvv(dest,src);
372 					}
373 				}
374 				break;
375 			case TYPE_VECTOR:
376 				{
377 					int			p;
378 					const float	*src	=	(const float *) val;
379 					float		*dest	=	(float *)		cParameter->defaultValue;
380 
381 					for (p=cParameter->numItems;p>0;p--,dest+=3,src+=3) {
382 						mulmv(dest,xform->from,src);
383 					}
384 				}
385 				break;
386 			case TYPE_NORMAL:
387 				{
388 					int			p;
389 					const float	*src	=	(const float *) val;
390 					float		*dest	=	(float *)		cParameter->defaultValue;
391 
392 					for (p=cParameter->numItems;p>0;p--,dest+=3,src+=3) {
393 						mulmn(dest,xform->to,src);
394 					}
395 				}
396 				break;
397 			case TYPE_POINT:
398 				{
399 					int			p;
400 					const float	*src	=	(const float *) val;
401 					float		*dest	=	(float *)		cParameter->defaultValue;
402 
403 					for (p=cParameter->numItems;p>0;p--,dest+=3,src+=3) {
404 						mulmp(dest,xform->from,src);
405 					}
406 				}
407 				break;
408 			case TYPE_MATRIX:
409 				{
410 					const float	*src	=	(const float *) val;
411 					float		*dest	=	(float *)		cParameter->defaultValue;
412 					memcpy(dest,src,cParameter->numItems*sizeof(matrix));
413 				}
414 				break;
415 			case TYPE_QUAD:
416 				{
417 					const float	*src	=	(const float *) val;
418 					float		*dest	=	(float *)		cParameter->defaultValue;
419 					memcpy(dest,src,cParameter->numItems*sizeof(float)*4);
420 				}
421 				break;
422 			case TYPE_DOUBLE:
423 				{
424 					const float	*src	=	(const float *) val;
425 					float		*dest	=	(float *)		cParameter->defaultValue;
426 					memcpy(dest,src,cParameter->numItems*sizeof(float)*2);
427 				}
428 				break;
429 			case TYPE_STRING:
430 				{
431 					const char			**src	=	(const char **) val;
432 					char				**dest	=	(char **)		cParameter->defaultValue;
433 					int					t;
434 					CAllocatedString	*nString;
435 
436 					for (t=cParameter->numItems;t>0;t--) {
437 
438 						nString			=	new CAllocatedString;
439 						nString->string	=	strdup(*src++);
440 						nString->next	=	strings;
441 						strings			=	nString;
442 
443 						*dest++			=	nString->string;
444 					}
445 				}
446 				break;
447 			case TYPE_INTEGER:
448 				{
449 					// This should not be possible
450 					error(CODE_BUG,"Integer shader variable in shader \"%s\"\n",parent->name);
451 					const int	*src	=	(const int *)	val;
452 					int			*dest	=	(int *)			cParameter->defaultValue;
453 					memcpy(dest,src,cParameter->numItems*sizeof(int));
454 				}
455 				break;
456 			default:
457 				break;
458 			}
459 
460 			break;
461 		}
462 	}
463 
464 	return cParameter != NULL;
465 }
466 
467 ///////////////////////////////////////////////////////////////////////
468 // Class				:	CProgrammableShaderInstance
469 // Method				:	setParameters
470 // Description			:	Set the values of the parameters
471 // Return Value			:	-
472 // Comments				:
setParameters(int np,const char ** params,const void ** vals)473 void	CProgrammableShaderInstance::setParameters(int np,const char **params,const void **vals) {
474 	int	i;
475 
476 
477 	// Set the parameter defaults
478 	for (i=0;i<np;i++) {
479 		if (setParameter(params[i],vals[i]) == FALSE) {
480 			CVariable	var;
481 
482 			if (parseVariable(&var,NULL,params[i]) == TRUE) {
483 				if (setParameter(var.name,vals[i]) == FALSE) {
484 					error(CODE_BADTOKEN,"Parameter \"%s\" not found in the shader\n",var.name);
485 				}
486 			} else {
487 				error(CODE_BADTOKEN,"Parameter \"%s\" not found in the shader\n",params[i]);
488 			}
489 		}
490 	}
491 }
492 
493 ///////////////////////////////////////////////////////////////////////
494 // Class				:	CProgrammableShaderInstance
495 // Method				:	getParameter
496 // Description			:	Get the current value of a parameter
497 // Return Value			:	TRUE if successful, FALSE othervise
498 // Comments				:	The second void * must be float *
499 //							if the type of the parameter is float/vector/matrix
500 //							and char ** if the type of the parameter is string.
501 //							iff var or globalIndex is NULL, we skip any parameters
502 //							which are mutable
getParameter(const char * name,void * dest,CVariable ** var,int * globalIndex)503 int		CProgrammableShaderInstance::getParameter(const char *name,void *dest,CVariable **var,int *globalIndex) {
504 	int							j;
505 	int							globalNumber = 0;
506 	float						*destFloat;
507 	const float					*srcFloat;
508 	const char					**destString;
509 	const char					**srcString;
510 	int							*destInt;
511 	const int					*srcInt;
512 	CVariable					*cParameter;
513 
514 	// BEWARE!
515 	// the instance parameters are stored in the opposite order to the
516 	// parent shader parameters.  The counting scheme for globals used here must
517 	// match that used when saving lights.  In both cases, we loop the instance
518 	// not the parent parameters
519 
520 	for (cParameter=parameters;cParameter!=NULL;cParameter=cParameter->next) {
521 
522 		// retrieve the storage in which the parameter lives
523 		const int storage = cParameter->storage;
524 		if (strcmp(name,cParameter->name) == 0) {
525 
526 			// Note: all parameters have storage, but for lights
527 			// all we have to save in the light cache are the mutable ones
528 			// We also only return defaults for interior and exterior (var == NULL)
529 			if (!(storage == STORAGE_PARAMETER && parent->type == SL_LIGHTSOURCE) && (var != NULL) && (globalIndex != NULL)) {
530 				*var			=	cParameter;
531 				*globalIndex	=	globalNumber;
532 				return TRUE;
533 			}
534 
535 			switch(cParameter->type) {
536 			case TYPE_FLOAT:
537 				destFloat	=	(float *)		dest;
538 				srcFloat	=	(const float *)	cParameter->defaultValue;
539 				for (j=cParameter->numItems;j>0;j--)
540 					*destFloat++	=	*srcFloat++;
541 				break;
542 			case TYPE_COLOR:
543 			case TYPE_VECTOR:
544 			case TYPE_NORMAL:
545 			case TYPE_POINT:
546 				destFloat	=	(float *)		dest;
547 				srcFloat	=	(const float *)	cParameter->defaultValue;
548 				for (j=cParameter->numItems;j>0;j--,destFloat+=3,srcFloat+=3)
549 					movvv(destFloat,srcFloat);
550 				break;
551 			case TYPE_MATRIX:
552 				destFloat	=	(float *)		dest;
553 				srcFloat	=	(const float *)	cParameter->defaultValue;
554 				for (j=cParameter->numItems;j>0;j--,destFloat+=16,srcFloat+=16)
555 					movmm(destFloat,srcFloat);
556 				break;
557 			case TYPE_QUAD:
558 				destFloat	=	(float *)		dest;
559 				srcFloat	=	(const float *)	cParameter->defaultValue;
560 				for (j=cParameter->numItems;j>0;j--,destFloat+=4,srcFloat+=4)
561 					movqq(destFloat,srcFloat);
562 				break;
563 			case TYPE_DOUBLE:
564 				destFloat	=	(float *)		dest;
565 				srcFloat	=	(const float *)	cParameter->defaultValue;
566 				for (j=cParameter->numItems;j>0;j--) {
567 					*destFloat++	=	*srcFloat++;
568 					*destFloat++	=	*srcFloat++;
569 				}
570 				break;
571 			case TYPE_STRING:
572 				destString	=	(const char **) dest;
573 				srcString	=	(const char **)	cParameter->defaultValue;
574 				for (j=cParameter->numItems;j>0;j--)
575 					*destString++	=	*srcString++;
576 				break;
577 			case TYPE_INTEGER:
578 				// This should not be possible
579 				error(CODE_BUG,"Integer shader variable in shader \"%s\"\n",name);
580 				destInt		=	(int *)			dest;
581 				srcInt		=	(const int *)	cParameter->defaultValue;
582 				for (j=cParameter->numItems;j>0;j--)
583 					*destInt++	=	*srcInt++;
584 				break;
585 			default:
586 				break;
587 			}
588 
589 			return	TRUE;
590 		} else {
591 			if (!(storage == STORAGE_PARAMETER && parent->type == SL_LIGHTSOURCE))	globalNumber++;
592 		}
593 	}
594 
595 	return FALSE;
596 }
597 
598 
599 ///////////////////////////////////////////////////////////////////////
600 // Class				:	CProgrammableShaderInstance
601 // Method				:	execute
602 // Description			:	Actually execute the shader
603 // Return Value			:	-
604 // Comments				:
execute(CShadingContext * context,float ** locals)605 void			CProgrammableShaderInstance::execute(CShadingContext *context,float **locals) {
606 	context->execute(this,locals);
607 }
608 
609 ///////////////////////////////////////////////////////////////////////
610 // Class				:	CProgrammableShaderInstance
611 // Method				:	requiredParameters
612 // Description			:	Return the required parameters
613 // Return Value			:	-
614 // Comments				:
requiredParameters()615 unsigned int	CProgrammableShaderInstance::requiredParameters() {
616 	return parent->usedParameters;
617 }
618 
619 
620 
621 ///////////////////////////////////////////////////////////////////////
622 // Class				:	CProgrammableShaderInstance
623 // Method				:	getName
624 // Description			:	Get the name of the shader
625 // Return Value			:	-
626 // Comments				:
getName()627 const char		*CProgrammableShaderInstance::getName() {
628 	return parent->name;
629 }
630 
631 ///////////////////////////////////////////////////////////////////////
632 // Class				:	CProgrammableShaderInstance
633 // Method				:	illuminate
634 // Description			:	Illuminate the shading state is a lightsource shader
635 // Return Value			:	-
636 // Comments				:
illuminate(CShadingContext * context,float ** locals)637 void			CProgrammableShaderInstance::illuminate(CShadingContext *context,float **locals) {
638 
639 	// This function should never be called for non-light shaders
640 	assert(parent->type == SL_LIGHTSOURCE);
641 	context->execute(this,locals);
642 }
643 
644 
645 
646 ///////////////////////////////////////////////////////////////////////
647 // Class				:	CProgrammableShaderInstance
648 // Method				:	prepare
649 // Description			:	Allocate the cache and set the parameter defaults
650 // Return Value			:	-
651 // Comments				:
prepare(CMemPage * & namedMemory,float ** varying,int numVertices)652 float			**CProgrammableShaderInstance::prepare(CMemPage *&namedMemory,float **varying,int numVertices) {
653 	CVariable	*cVariable;
654 	char		*data;
655 	float		**locals;
656 	int			totalVaryingSize;
657 	int			i;
658 
659 	// Get const pointers for fast access
660 	const int	numVariables	=	parent->numVariables;
661 	const int	*varyingSizes	=	parent->varyingSizes;
662 
663 	// Compute the total memory we will need for the shader parameters
664 	for (totalVaryingSize=0,i=0;i<numVariables;i++) {
665 		if (varyingSizes[i] < 0)	totalVaryingSize	+=	-varyingSizes[i];
666 		else						totalVaryingSize	+=	varyingSizes[i]*numVertices*3;
667 	}
668 
669 	// Allocate memory for the temporary shader variables
670 	// Allocate some extra space for alignment
671 	data	=	(char *) ralloc(totalVaryingSize + numVariables*(sizeof(float *) + sizeof(float)),namedMemory);
672 	locals	=	(float **) data;
673 	data	+=	numVariables*sizeof(float*);
674 
675 	// Save the memory
676 	for (i=0;i<numVariables;i++) {
677 
678 		// Align the data to 64 bits
679 		data	=	(char *) align64(data);
680 
681 		locals[i]	=	(float*) data;
682 		if (varyingSizes[i] < 0)	data	+=	-varyingSizes[i];
683 		else						data	+=	varyingSizes[i]*numVertices*3;
684 	}
685 
686 	// For each parameter, copy over the default value of the parameter
687 	for (cVariable=parameters;cVariable!=NULL;cVariable=cVariable->next) {
688 		float		*destf;
689 		const float	*srcf;
690 		const char	**dests;
691 		const char	**srcs;
692 
693 		// Find where we're writing
694 		if (cVariable->storage == STORAGE_GLOBAL)	{
695 			destf					=	(float *) varying[cVariable->entry];
696 			dests					=	(const char **) varying[cVariable->entry];
697 		} else {
698 			assert(cVariable->entry < numVariables);
699 			destf					=	(float *) locals[cVariable->entry];
700 			dests					=	(const char **) locals[cVariable->entry];
701 		}
702 
703 		// This is the repetition amount
704 		if ((cVariable->container == CONTAINER_UNIFORM) || (cVariable->container == CONTAINER_CONSTANT)) {
705 
706 			//assert(cVariable->numFloats == -parent->varyingSizes[cVariable->entry]);
707 
708 			if (cVariable->type == TYPE_STRING) {
709 				if ((srcs = (const char **) cVariable->defaultValue) != NULL) {
710 					int	i;
711 					for (i=cVariable->numFloats;i>0;i--)	*dests++	=	*srcs++;
712 				}
713 			} else {
714 				if ((srcf = (const float *) cVariable->defaultValue) != NULL) {
715 					int	i;
716 					for (i=cVariable->numFloats;i>0;i--)	*destf++	=	*srcf++;
717 				}
718 			}
719 		} else {
720 
721 			//assert(cVariable->numFloats == parent->varyingSizes[cVariable->entry]);
722 
723 			if (cVariable->type == TYPE_STRING) {
724 				if ((srcs = (const char **) cVariable->defaultValue) != NULL) {
725 					int			n;
726 					const int	c	=	cVariable->numFloats;
727 
728 					// FIXME: We may want to unroll these two loops
729 					for(n=numVertices*3;n>0;n--) {
730 						for (i=0;i<c;i++)	*dests++	=	srcs[i];
731 					}
732 				}
733 			} else {
734 				if ((srcf = (const float *) cVariable->defaultValue) != NULL) {
735 					int			n;
736 					const int	c	=	cVariable->numFloats;
737 
738 					// FIXME: We may want to unroll these two loops
739 					for(n=numVertices*3;n>0;n--) {
740 						for (i=0;i<c;i++)	*destf++	=	srcf[i];
741 					}
742 				}
743 			}
744 		}
745 	}
746 
747 	return (float **) locals;
748 }
749 
750 
751 
752 
753 
754 
755 ///////////////////////////////////////////////////////////////////////
756 // Function				:	debugFunction
757 // Description			:	This function is used to debugging purposes
758 // Return Value			:	-
759 // Comments				:	You can trigger this function from the compiled shader
760 //							code by debug ("f=o")
debugFunction(float * op)761 void	debugFunction(float *op) {
762 	fprintf(stderr,"Debug\n");
763 }
764 
765