////////////////////////////////////////////////////////////////////// // // Pixie // // Copyright © 1999 - 2003, Okan Arikan // // Contact: okan@cs.berkeley.edu // // This library 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 library 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 library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // File : pl.cpp // Classes : // Description : Parameter list class implementation // //////////////////////////////////////////////////////////////////////// #include #include #include "pl.h" #include "renderer.h" #include "stats.h" #include "error.h" #include "memory.h" /////////////////////////////////////////////////////////////////////// // Class : CParameter // Method : CParameter // Description : Ctor // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter::CParameter() { stats.numParameters++; next = NULL; } /////////////////////////////////////////////////////////////////////// // Class : CParameter // Method : ~CParameter // Description : Dtor // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter::~CParameter() { stats.numParameters--; if (next != NULL) delete next; } /////////////////////////////////////////////////////////////////////// // Class : CUniformParameter // Description : Encapsulates a uniform parameter // Comments : // Date last edited : 8/17/2003 class CUniformParameter : public CParameter { public: CUniformParameter() : CParameter() { data = NULL; } ~CUniformParameter() { assert(data != NULL); delete [] data; } void dispatch(int numVertices,float **varying) { memcpy(varying[variable->entry],data,variable->numFloats*sizeof(float)); if (next != NULL) next->dispatch(numVertices,varying); } void dispatch(int start,int numVertices,float **varying) { memcpy(varying[variable->entry] + start*variable->numFloats,data,variable->numFloats*sizeof(float)); if (next != NULL) next->dispatch(start,numVertices,varying); } CParameter *clone() { CUniformParameter *cUniform = new CUniformParameter; cUniform->variable = variable; cUniform->data = new float[variable->numFloats]; memcpy(cUniform->data,data,variable->numFloats*sizeof(float)); if (next != NULL) cUniform->next = next->clone(); return cUniform; } const CVariable *variable; float *data; }; /////////////////////////////////////////////////////////////////////// // Class : CUniformParameter // Description : Encapsulates a varying parameter // Comments : // Date last edited : 8/17/2003 class CVaryingParameter : public CParameter { public: CVaryingParameter() : CParameter() { data = NULL; } ~CVaryingParameter() { delete [] data; } void dispatch(int numVertices,float **varying) { int i,j; float *dest = varying[variable->entry]; const int numFloats = variable->numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v2 = v1 + numFloats; const float *v3 = v2 + numFloats; const float *u = varying[VARIABLE_U]; const float *v = varying[VARIABLE_V]; for (i=numVertices;i>0;i--) { const float cu = *u++; const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } void dispatch(int start,int numVertices,float **varying) { int i,j; const int numFloats = variable->numFloats; float *dest = varying[variable->entry] + start*numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v2 = v1 + numFloats; const float *v3 = v2 + numFloats; const float *u = varying[VARIABLE_U] + start; const float *v = varying[VARIABLE_V] + start; for (i=numVertices;i>0;i--) { const float cu = *u++; const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } CParameter *clone() { CVaryingParameter *cVarying = new CVaryingParameter; cVarying->variable = variable; cVarying->data = new float[variable->numFloats*4]; memcpy(cVarying->data,data,variable->numFloats*4*sizeof(float)); if (next != NULL) cVarying->next = next->clone(); return cVarying; } const CVariable *variable; float *data; }; /////////////////////////////////////////////////////////////////////// // Class : CUniformParameter // Description : Encapsulates a varying parameter // Comments : // Date last edited : 8/17/2003 class CVarying3Parameter : public CParameter { public: CVarying3Parameter() : CParameter() { data = NULL; } ~CVarying3Parameter() { delete [] data; } void dispatch(int numVertices,float **varying) { int i,j; float *dest = varying[variable->entry]; const int numFloats = variable->numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v2 = v1 + numFloats; const float *u = varying[VARIABLE_U]; const float *v = varying[VARIABLE_V]; for (i=numVertices;i>0;i--) { const float cu = *u++; const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } void dispatch(int start,int numVertices,float **varying) { int i,j; const int numFloats = variable->numFloats; float *dest = varying[variable->entry] + start*numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v2 = v1 + numFloats; const float *u = varying[VARIABLE_U] + start; const float *v = varying[VARIABLE_V] + start; for (i=numVertices;i>0;i--) { const float cu = *u++; const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } CParameter *clone() { CVarying3Parameter *cVarying = new CVarying3Parameter; cVarying->variable = variable; cVarying->data = new float[variable->numFloats*3]; memcpy(cVarying->data,data,variable->numFloats*3*sizeof(float)); if (next != NULL) cVarying->next = next->clone(); return cVarying; } const CVariable *variable; float *data; }; /////////////////////////////////////////////////////////////////////// // Class : CVarying2Parameter // Description : Encapsulates a varying parameter // Comments : // Date last edited : 8/17/2003 class CVarying2Parameter : public CParameter { public: CVarying2Parameter() : CParameter() { data = NULL; } ~CVarying2Parameter() { delete [] data; } void dispatch(int numVertices,float **varying) { int i,j; float *dest = varying[variable->entry]; const int numFloats = variable->numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v = varying[VARIABLE_V]; for (i=numVertices;i>0;i--) { const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } void dispatch(int start,int numVertices,float **varying) { int i,j; const int numFloats = variable->numFloats; float *dest = varying[variable->entry] + start*numFloats; const float *v0 = data; const float *v1 = v0 + numFloats; const float *v = varying[VARIABLE_V] + start; for (i=numVertices;i>0;i--) { const float cv = *v++; for (j=0;jdispatch(numVertices,varying); } CParameter *clone() { CVarying2Parameter *cVarying = new CVarying2Parameter; cVarying->variable = variable; cVarying->data = new float[variable->numFloats*2]; memcpy(cVarying->data,data,variable->numFloats*2*sizeof(float)); if (next != NULL) cVarying->next = next->clone(); return cVarying; } const CVariable *variable; float *data; }; #define dispatchData(__src,__dest,__size,__numFloats,__numVertices) \ int __tmp,__tmp2; \ switch(__numFloats) { \ case 0: \ break; \ case 1: \ for (__tmp=__numVertices;__tmp>0;__tmp--,__src+=__size) \ *__dest++ = *__src; \ break; \ case 2: \ for (__tmp=__numVertices;__tmp>0;__tmp--,__src+=__size) { \ *__dest++ = __src[0]; \ *__dest++ = __src[1]; \ } \ break; \ case 3: \ for (__tmp=__numVertices;__tmp>0;__tmp--,__src+=__size) { \ *__dest++ = __src[0]; \ *__dest++ = __src[1]; \ *__dest++ = __src[2]; \ } \ break; \ default: \ for (__tmp=__numVertices;__tmp>0;__tmp--,__src+=__size) { \ for (__tmp2=0;__tmp2<__numFloats;__tmp2++) { \ *__dest++ = __src[__tmp2]; \ } \ } \ break; \ } /////////////////////////////////////////////////////////////////////// // Class : CVertexData // Method : CVertexData // Description : Ctor // Return Value : // Comments : // Date last edited : 8/19/2003 CVertexData::CVertexData() { stats.numVertexDatas++; stats.gprimCoreMemory += sizeof(CVertexData); refCount = 0; } /////////////////////////////////////////////////////////////////////// // Class : CVertexData // Method : ~CVertexData // Description : Dtor // Return Value : // Comments : // Date last edited : 8/19/2003 CVertexData::~CVertexData() { stats.numVertexDatas--; stats.gprimCoreMemory -= (sizeof(CVertexData) + numVariables*sizeof(CVariable *)); delete [] variables; } /////////////////////////////////////////////////////////////////////// // Class : CVertexData // Method : dispatch // Description : Dispatch vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 void CVertexData::dispatch(const float *data,int start,int numVertices,float **varying) { int i; CVariable **dispatch = variables; for (i=numVariables;i>0;i--,dispatch++) { const int entry = dispatch[0]->entry; const int numFloats = dispatch[0]->numFloats; const float *src = data; float *dest = varying[entry] + start*numFloats; dispatchData(src,dest,vertexSize,numFloats,numVertices); data += numFloats; } } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : CPl // Description : Ctor // Return Value : // Comments : // Date last edited : 8/19/2003 CPl::CPl(int dataSize,int numParameters,CPlParameter *p,float *d0,float *d1) { stats.numPls++; stats.gprimCoreMemory += sizeof(CPl) + numParameters*sizeof(CPlParameter); this->dataSize = dataSize; this->numParameters = numParameters; this->parameters = new CPlParameter[numParameters]; memcpy(this->parameters,p,numParameters*sizeof(CPlParameter)); this->data0 = d0; this->data1 = d1; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : ~CPl // Description : Dtor // Return Value : // Comments : // Date last edited : 8/19/2003 CPl::~CPl() { stats.numPls--; stats.gprimCoreMemory -= sizeof(CPl); if (parameters != NULL) { delete [] parameters; stats.gprimCoreMemory -= numParameters*sizeof(CPlParameter); } if (data0 != NULL) { delete [] data0; stats.gprimCoreMemory -= dataSize*sizeof(float); } if (data1 != NULL) { delete [] data1; stats.gprimCoreMemory -= dataSize*sizeof(float); } } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : append // Description : Append another data block for the shutter close // Return Value : // Comments : // Date last edited : 8/19/2003 void CPl::append(float *d) { if (data1 == NULL) { data1 = new float[dataSize]; stats.gprimCoreMemory += dataSize*sizeof(float); } memcpy(data1,d,sizeof(float)*dataSize); } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : transform // Description : Transform the variables into another coordinaye system // Return Value : // Comments : // Date last edited : 8/19/2003 void CPl::transform(CXform *x,float *cData) { if (cData == NULL) { if ((x->next != NULL) && (data1 == NULL)) { data1 = new float[dataSize]; memcpy(data1,data0,dataSize*sizeof(float)); stats.gprimCoreMemory += dataSize*sizeof(float); } if (data0 != NULL) transform(x,data0); if (data1 != NULL) transform(x,data1); } else { int i,j; float *src; const CPlParameter *cPl = parameters; const float *from,*to; if (x->next != NULL) { if (cData == data1) { from = x->next->from; to = x->next->to; } else { from = x->from; to = x->to; } } else { from = x->from; to = x->to; } for (i=numParameters;i>0;i--,cPl++) { const CVariable *cVar = cPl->variable; switch(cVar->type) { case TYPE_FLOAT: case TYPE_COLOR: // No transformation is required break; case TYPE_VECTOR: // Vector transform for (src=cData,j=cPl->numItems;j>0;j--,src+=3) { mulmv(src,from,src); } break; case TYPE_NORMAL: // Vector transform for (src=cData,j=cPl->numItems;j>0;j--,src+=3) { mulmn(src,to,src); } break; case TYPE_POINT: // Vector transform for (src=cData,j=cPl->numItems;j>0;j--,src+=3) { mulmp(src,from,src); } break; case TYPE_MATRIX: break; case TYPE_QUAD: // Vector transform for (src=cData,j=cPl->numItems;j>0;j--,src+=4) { mulmp4(src,from,src); } break; case TYPE_DOUBLE: case TYPE_STRING: case TYPE_INTEGER: case TYPE_BOOLEAN: // No transformation is required break; } cData += cPl->numItems*cVar->numFloats; } } } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertexData // Description : Extract the vertex data from the parameter list // Return Value : // Comments : // Date last edited : 8/19/2003 CVertexData *CPl::vertexData() { int i,j; CVertexData *vd = new CVertexData; int vertexSize; int param; // Count the number of vertices we have for (j=0,i=0;inumVariables = j; vd->variables = new CVariable*[j]; stats.gprimCoreMemory += j*sizeof(CVariable *); // Set the parameters vertexSize = 0; param = 0; for (j=0,i=0;ivariables[j++] = parameters[i].variable; vertexSize += parameters[i].variable->numFloats; } param |= parameters[i].variable->usageMarker; } vd->refCount = 0; vd->vertexSize = vertexSize; vd->parameters = param; vd->moving = (data1 == NULL ? FALSE : TRUE); return vd; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertexData // Description : Extract the vertex data from the parameter list // Return Value : // Comments : // Date last edited : 8/19/2003 CPl *CPl::clone() { float *ndata0,*ndata1; // Copy the data if (data0 != NULL) { stats.gprimCoreMemory += dataSize*sizeof(float); ndata0 = new float[dataSize]; memcpy(ndata0,data0,dataSize*sizeof(float)); } else { ndata0 = NULL; } if (data1 != NULL) { stats.gprimCoreMemory += dataSize*sizeof(float); ndata1 = new float[dataSize]; memcpy(ndata1,data1,dataSize*sizeof(float)); } else { ndata1 = NULL; } return new CPl(dataSize,numParameters,parameters,ndata0,ndata1); } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : find // Description : Find a variable in the parameter list // Return Value : // Comments : // Date last edited : 8/19/2003 CPlParameter *CPl::find(int t,const float *&d0,const float *&d1) { int i,disp; for (disp=0,i=0;ientry == t) { d0 = data0 + disp; d1 = (data1 == NULL ? NULL : data1 + disp); return parameters+i; } disp += parameters[i].numItems*parameters[i].variable->numFloats; } return NULL; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 void CPl::collect(int &size,float *&data,EVariableClass container) { int i,j,k; const float *cData = data0; float *oData; int vs = 0; int numItems = 0; for (i=0;inumFloats; numItems = parameters[i].numItems; } } if (data1 != NULL) { size = vs*2; } else { size = vs; } if (vs == 0) return; assert(numItems > 0); if (data == NULL) data = (float *) ralloc(size*numItems*sizeof(float)); oData = data; for (i=0;inumFloats; if (parameters[i].container == container) { const float *sData = cData; float *dData = oData; for (j=parameters[i].numItems;j>0;j--,dData+=(size-numFloats)) { for (k=numFloats;k>0;k--) *dData++ = *sData++; } oData += numFloats; } cData += parameters[i].numItems*numFloats; } if (data1 != NULL) { cData = data1; for (i=0;inumFloats; if (parameters[i].container == container) { const float *sData = cData; float *dData = oData; for (j=parameters[i].numItems;j>0;j--,dData+=(size-numFloats)) { for (k=numFloats;k>0;k--) *dData++ = *sData++; } oData += numFloats; } cData += parameters[i].numItems*numFloats; } } } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : uniform // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::uniform(int u,CParameter *p) { int i; const float *cData = data0; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_UNIFORM) { CUniformParameter *np = new CUniformParameter; np->variable = cVariable; np->data = new float[numFloats]; memcpy(np->data,cData+u*numFloats,numFloats*sizeof(float)); np->next = p; p = np; } else if (cParameter->container == CONTAINER_CONSTANT) { CUniformParameter *np = new CUniformParameter; np->variable = cVariable; np->data = new float[numFloats]; memcpy(np->data,cData,numFloats*sizeof(float)); np->next = p; p = np; } cData += cParameter->numItems*numFloats; } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::varying(int v0,int v1,int v2,int v3,CParameter *p) { int i; const float *cData = data0; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_VARYING) { CVaryingParameter *np = new CVaryingParameter; np->variable = cVariable; np->data = new float[numFloats*4]; memcpy(np->data+0*numFloats,cData+v0*numFloats,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,cData+v1*numFloats,numFloats*sizeof(float)); memcpy(np->data+2*numFloats,cData+v2*numFloats,numFloats*sizeof(float)); memcpy(np->data+3*numFloats,cData+v3*numFloats,numFloats*sizeof(float)); np->next = p; p = np; } cData += cParameter->numItems*numFloats; } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::varying(int v0,int v1,CParameter *p) { int i; const float *cData = data0; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_VARYING) { CVarying2Parameter *np = new CVarying2Parameter; np->variable = cVariable; np->data = new float[numFloats*2]; memcpy(np->data+0*numFloats,cData+v0*numFloats,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,cData+v1*numFloats,numFloats*sizeof(float)); np->next = p; p = np; } cData += cParameter->numItems*numFloats; } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::varying(float *v0,float *v1,float *v2,float *v3,CParameter *p) { int i; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_VARYING) { CVaryingParameter *np = new CVaryingParameter; np->variable = cVariable; np->data = new float[numFloats*4]; memcpy(np->data+0*numFloats,v0,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,v1,numFloats*sizeof(float)); memcpy(np->data+2*numFloats,v2,numFloats*sizeof(float)); memcpy(np->data+3*numFloats,v3,numFloats*sizeof(float)); np->next = p; p = np; v0 += numFloats; v1 += numFloats; v2 += numFloats; v3 += numFloats; } } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::facevarying(int v0,int v1,int v2,int v3,CParameter *p) { int i; const float *cData = data0; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_FACEVARYING) { CVaryingParameter *np = new CVaryingParameter; np->variable = cVariable; np->data = new float[numFloats*4]; memcpy(np->data+0*numFloats,cData+v0*numFloats,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,cData+v1*numFloats,numFloats*sizeof(float)); memcpy(np->data+2*numFloats,cData+v2*numFloats,numFloats*sizeof(float)); memcpy(np->data+3*numFloats,cData+v3*numFloats,numFloats*sizeof(float)); np->next = p; p = np; } cData += cParameter->numItems*numFloats; } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::facevarying(float *v0,float *v1,float *v2,float *v3,CParameter *p) { int i; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_FACEVARYING) { CVaryingParameter *np = new CVaryingParameter; np->variable = cVariable; np->data = new float[numFloats*4]; memcpy(np->data+0*numFloats,v0,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,v1,numFloats*sizeof(float)); memcpy(np->data+2*numFloats,v2,numFloats*sizeof(float)); memcpy(np->data+3*numFloats,v3,numFloats*sizeof(float)); np->next = p; p = np; v0 += numFloats; v1 += numFloats; v2 += numFloats; v3 += numFloats; } } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : vertices // Description : Extract the vertex data // Return Value : // Comments : // Date last edited : 8/19/2003 CParameter *CPl::facevarying(int v0,int v1,int v2,CParameter *p) { int i; const float *cData = data0; CPlParameter *cParameter = parameters; for (i=numParameters;i>0;i--,cParameter++) { const CVariable *cVariable = cParameter->variable; const int numFloats = cVariable->numFloats; if (cParameter->container == CONTAINER_FACEVARYING) { CVarying3Parameter *np = new CVarying3Parameter; np->variable = cVariable; np->data = new float[numFloats*3]; memcpy(np->data+0*numFloats,cData+v0*numFloats,numFloats*sizeof(float)); memcpy(np->data+1*numFloats,cData+v1*numFloats,numFloats*sizeof(float)); memcpy(np->data+2*numFloats,cData+v2*numFloats,numFloats*sizeof(float)); np->next = p; p = np; } cData += cParameter->numItems*numFloats; } return p; } /////////////////////////////////////////////////////////////////////// // Class : CPl // Method : parameters // Description : Extracts the parameters set by the list // Return Value : // Comments : // Date last edited : 8/19/2003 unsigned int CPl::parameterUsage() { unsigned int p; int i; for (p=0,i=0;iusageMarker; } return p; } /////////////////////////////////////////////////////////////////////// // Function : parseParameterList // Description : Parse a parameter list // Return Value : The parsed parameter list // Comments : // Date last edited : 8/19/2003 CPl *parseParameterList(int numUniform,int numVertex,int numVarying,int numFaceVarying,int numParams,char **params,void **vals,char *required,int flags) { int i; CPlParameter *parameters; int dataSize; float *data; float *cData; // Resolve the variables parameters = (CPlParameter *) alloca(numParams*sizeof(CPlParameter)); for (dataSize=0,i=0;iretrieveVariable(params[i]); if (cVar == NULL) { // This may be an inline decl., try to parse it into a temp var if (parseVariable(&tmp,NULL,params[i])) { // Save the declared container and fetch the variable container = tmp.container; declaredParam = TRUE; cVar = currentRenderer->retrieveVariable(tmp.name); if (cVar == NULL) { // No such variable has been declared, declare it cVar = currentRenderer->declareVariable(NULL,params[i]); } } } else { container = cVar->container; } // Did we find the variable ? if (cVar == NULL) { error(CODE_BADTOKEN,"Parameter \"%s\" not defined\n",params[i]); return NULL; } // All primitive parameters must be global if (cVar->global == FALSE) { currentRenderer->makeGlobalVariable(cVar); } // Do necessary conversions if (flags & PL_VARYING_TO_VERTEX) { if (container == CONTAINER_VARYING) container = CONTAINER_VERTEX; } if (flags & PL_VERTEX_TO_VARYING) { if (container == CONTAINER_VERTEX) container = CONTAINER_VARYING; } // Size check switch(container) { case CONTAINER_UNIFORM: numItems = numUniform; break; case CONTAINER_VERTEX: numItems = numVertex; break; case CONTAINER_VARYING: numItems = numVarying; break; case CONTAINER_FACEVARYING: numItems = numFaceVarying; break; case CONTAINER_CONSTANT: numItems = 1; break; } // Treat "st" differently if (strcmp(cVar->name,"st") == 0) { CPl *npl; memBegin(); char **ntokens = (char **) ralloc((numParams+1)*sizeof(char *)); void **nvals = (void **) ralloc((numParams+1)*sizeof(void *)); int j; float *sval,*tval,*src; sval = (float *) ralloc(numItems*sizeof(float)); tval = (float *) ralloc(numItems*sizeof(float)); src = (float *) vals[i]; // Separate s and t for (j=0;jnumFloats; } // Check the required parameter if (required != NULL) { for (i=0;iname,required) == 0) { // Make sure that the first parameter is always the required one if (i != 0) { CPlParameter tmp = parameters[0]; void *vtmp = vals[0]; parameters[0] = parameters[i]; vals[0] = vals[i]; parameters[i] = tmp; vals[i] = vtmp; } break; } } // Required parameter is missing if (i == numParams) { error(CODE_MISSINGDATA,"Required parameter \"%s\" is missing\n",required); return NULL; } } // Allocate the data field cData = data = new float[dataSize]; stats.gprimCoreMemory += dataSize*sizeof(float); // Save the data for (i=0;inumFloats); cData += num*cVar->numFloats; } // Return the parameter list return new CPl(dataSize,numParams,parameters,data); }