void ShaderParameterCg::Set(std::vector<glm::mat4x4> const& matrices) { if (!this->_preBuffer) { this->_preBuffer.reset(new std::vector<float>( cgGetParameterColumns(this->_param) * cgGetParameterRows(this->_param) * cgGetArrayTotalSize(this->_param) )); } std::memcpy(this->_preBuffer->data(), matrices.data(), sizeof(float) * std::min(this->_preBuffer->size(), matrices.size() * 4*4)); cgSetParameterValuefc(this->_param, (int)this->_preBuffer->size(), this->_preBuffer->data()); }
void cEffect::SetParam(const std::string &lacName, const float * lfParam, int liCount ) { static const unsigned kuiAuxiliarBuffer = 256 * 4; static float gFullArray[kuiAuxiliarBuffer]; CGparameter lParam = cgGetNamedEffectParameter(mEffect, lacName.c_str()); if (lParam) { int liNRows = cgGetParameterRows(lParam); int liNCols = cgGetParameterColumns(lParam); int liASize = cgGetArrayTotalSize(lParam); int liNTotal = liNRows*liNCols; if (liASize > 0) { liNTotal *= liASize; if ( liCount < liNTotal ) { assert(kuiAuxiliarBuffer > liNTotal); assert(kuiAuxiliarBuffer > liCount); memcpy(gFullArray, lfParam, sizeof(float) * liCount); cgSetParameterValuefr(lParam, liNTotal, gFullArray); } else { cgSetParameterValuefr(lParam, liCount, lfParam); } CGerror err = cgGetError(); if (err != CG_NO_ERROR) { OutputDebugStr(cgGetErrorString( err )); OutputDebugStr("\n"); } } } }
static void AddParameter(JSON &json, CGparameter param) { const char * const parameterName = cgGetParameterName(param); if (sVerbose) { puts(parameterName); } json.AddObject(parameterName); const CGtype type = cgGetParameterType(param); const CGtype baseType = cgGetParameterBaseType(param); int numRows = cgGetParameterRows(param); const int numColumns = cgGetParameterColumns(param); if (CG_ARRAY == type) { const int totalArraySize = cgGetArrayTotalSize(param); numRows *= totalArraySize; } json.AddString("type", cgGetTypeString(baseType)); if (1 < numRows) { json.AddValue("rows", numRows); } if (1 < numColumns) { json.AddValue("columns", numColumns); } const int maxNumElements = (numColumns * numRows); int n; if (CG_FLOAT == baseType) { float * const values = (float *)malloc(maxNumElements * sizeof(float)); const int numValues = cgGetParameterValuefr(param, maxNumElements, values); if (numValues) { for (n = 0; n < numValues; n++) { if (values[n] != 0.0f) { break; } } if (n < numValues) { json.AddArray("values", true); json.BeginData(true); for (n = 0; n < numValues; n++) { json.AddData(values[n]); } json.EndData(); json.CloseArray(true); } } free(values); } else if (CG_INT == baseType) { int * const values = (int *)malloc(maxNumElements * sizeof(int)); const int numValues = cgGetParameterValueir(param, maxNumElements, values); if (numValues) { for (n = 0; n < numValues; n++) { if (values[n]) { break; } } if (n < numValues) { json.AddArray("values", true); json.BeginData(true); for (n = 0; n < numValues; n++) { json.AddData(values[n]); } json.EndData(); json.CloseArray(true); } } free(values); } else if (CG_BOOL == baseType) { int * const values = (int *)malloc(maxNumElements * sizeof(int)); const int numValues = cgGetParameterValueir(param, maxNumElements, values); if (numValues) { for (n = 0; n < numValues; n++) { if (values[n]) { break; } } if (n < numValues) { json.AddArray("values", true); json.BeginData(true); for (n = 0; n < numValues; n++) { json.AddData(values[n]); } json.EndData(); json.CloseArray(true); } } free(values); } json.CloseObject(); // parameter }
void cgfxVaryingParameter::setupAttributes( cgfxRCPtr<cgfxVertexAttribute>& vertexAttributes, CGprogram program) { // Make sure our parameter name is acceptable is a Maya attribute name MString attrName = fName; int lastDot = attrName.rindex( '.'); if( lastDot >= 0) attrName = attrName.substring( lastDot + 1, attrName.length() - 1); MString semanticName = cgGetParameterSemantic( fParameter); MString semantic(semanticName); cgGetParameterSemantic( fParameter); semantic.toUpperCase(); // Is this varying parameter packed or atomic? CGtype type = cgGetNamedUserType( program, attrName.asChar()); if( type != CG_UNKNOWN_TYPE) { // It's packed: explode the inputs into the structure elements CGcontext context = cgGetProgramContext( program); CGparameter packing = cgCreateParameter( context, type); fVertexStructure = new cgfxVaryingParameterStructure(); fVertexStructure->fLength = 0; fVertexStructure->fSize = 0; CGparameter element = cgGetFirstStructParameter( packing); while( element) { MString elementName = cgGetParameterName( element); int lastDot = elementName.rindex( '.'); if( lastDot >= 0) elementName = elementName.substring( lastDot + 1, elementName.length() - 1); cgfxRCPtr<cgfxVertexAttribute> attr = setupAttribute( elementName, semantic, element, vertexAttributes); fVertexStructure->fElements[ fVertexStructure->fLength].fVertexAttribute = attr; int size = cgGetParameterRows( element) * cgGetParameterColumns( element); CGtype type = cgGetParameterBaseType( element); if( type == CG_FLOAT) size *= sizeof( GLfloat); else if( type == CG_INT) size *= sizeof( GLint); fVertexStructure->fElements[ fVertexStructure->fLength].fSize = size; fVertexStructure->fLength++; fVertexStructure->fSize += size; element = cgGetNextParameter( element); } cgDestroyParameter( packing); } else { // It's atomic - create a single, simple input fVertexAttribute = setupAttribute( attrName, semantic, fParameter, vertexAttributes); } // Now pull apart the semantic string to work out where to bind // this value in open GL (as the automagic binding through cgGL // didn't work so well when this was written) int radix = 1; fGLIndex = 0; unsigned int length = semantic.length(); const char* str = semantic.asChar(); // If sematic is NULL then stop here, bug 327649 if (length == 0) { fGLType = glRegister::kUnknown; return; } for(;;) { char c = str[ length - 1]; if( c < '0' || c > '9') break; fGLIndex += radix * (c - '0'); radix *= 10; --length; } if( semantic.length() != length) semantic = semantic.substring( 0, length - 1); // Determine the semantic and setup the gl binding type we should use // to set this parameter. If there's a sensible default value, set that // while we're here. // Note there is no need to set the source type, this gets determined // when the vertex attribute sources are analysed if( semantic == "POSITION") { fGLType = glRegister::kPosition; fVertexAttribute->fSourceName = "position"; } else if( semantic == "NORMAL") { fGLType = glRegister::kNormal; if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "normal"; } else if( semantic == "TEXCOORD") { fGLType = glRegister::kTexCoord; if( fVertexAttribute.isNull() == false ) { if( attrName.toLowerCase() == "tangent") fVertexAttribute->fSourceName = "tangent:map1"; else if( attrName.toLowerCase() == "binormal") fVertexAttribute->fSourceName = "binormal:map1"; else fVertexAttribute->fSourceName = "uv:map1"; } } else if( semantic == "TANGENT") { fGLType = glRegister::kTexCoord; fGLIndex += 6; // TANGENT is TEXCOORD6 if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "tangent:map1"; } else if( semantic == "BINORMAL") { fGLType = glRegister::kTexCoord; fGLIndex += 7; // BINORMAL is TEXCOORD7 if( fVertexAttribute.isNull() == false ) fVertexAttribute->fSourceName = "binormal:map1"; } else if( semantic == "COLOR") { fGLType = fGLIndex == 1 ? glRegister::kSecondaryColor : glRegister::kColor; } else if( semantic == "ATTR") { fGLType = glRegister::kVertexAttrib; if( fVertexAttribute.isNull() == false ) { fVertexAttribute->fSourceName = semanticName; } } else if( semantic == "PSIZE") { fGLType = glRegister::kVertexAttrib; fGLIndex = 6; } else { fGLType = glRegister::kUnknown; } }
static int PubCGparam_func (PState pstate,PubFunction_t *fn, int n) { CGparameter cgparam = NULL; if ((int)fn->upvalue > PCG_GET && (n<1 || FunctionPublish_getArg(pstate,1,LUXI_CLASS_CGPARAM,(void*)&cgparam)<1)) return FunctionPublish_returnError(pstate,"1 cgparam required"); switch((int)fn->upvalue){ case PCG_NEW: { char *name; char *nametype; CGtype cgtype; CGtype basetype; int cnt = 1; if (n < 2 || FunctionPublish_getArg(pstate,3,LUXI_CLASS_STRING,(void*)&name,LUXI_CLASS_STRING,(void*)&nametype,LUXI_CLASS_INT,(void*)&cnt)<2) return FunctionPublish_returnError(pstate,"2 strings required"); cgtype = cgGetType(nametype); basetype = cgGetTypeBase(cgtype); if (VIDCg_getConnector(name) || cgtype==CG_UNKNOWN_TYPE || (basetype != CG_FLOAT && basetype != CG_INT && basetype != CG_BOOL)) return FunctionPublish_returnError(pstate,"name already in use, or illegal cg base type (float, bool, int)"); if (cgGetTypeClass(cgtype) == CG_PARAMETERCLASS_MATRIX && basetype != CG_FLOAT) return FunctionPublish_returnError(pstate,"only float matrix parameters allowed"); cgparam = cnt > 1 ? cgCreateParameterArray(g_VID.cg.context,cgtype,cnt) : cgCreateParameter(g_VID.cg.context,cgtype); VIDCg_setConnector(name,cgparam); return FunctionPublish_returnType(pstate,LUXI_CLASS_CGPARAM,(void*)cgparam); } break; case PCG_DELETE: { int linked = cgGetNumConnectedToParameters(cgparam); if (linked == 0){ VIDCg_setConnector(cgGetParameterName(cgparam),NULL); cgDestroyParameter(cgparam); } return FunctionPublish_returnInt(pstate,linked); } break; case PCG_GET: { char *name; if (n < 1 || !FunctionPublish_getArg(pstate,1,LUXI_CLASS_STRING,(void*)&name)) return FunctionPublish_returnError(pstate,"1 string required"); cgparam = VIDCg_getConnector(name); if (cgparam) return FunctionPublish_returnType(pstate,LUXI_CLASS_CGPARAM,(void*)cgparam); else return 0; } break; case PCG_VALUE: { CGtype cgtype = cgGetParameterType(cgparam); CGtype basetype = cgGetTypeBase(cgtype); CGtype classtype = cgGetTypeClass(cgtype); lxClassType ctype; Reference ref; float *matrix; StaticArray_t *starray; int read = 0; int offset = 0; int size; int into = (int)fn->upvalue == PCG_VALUEINTO; if (n==1 || into){ int vector[4]; switch(classtype){ case CG_PARAMETERCLASS_SCALAR: case CG_PARAMETERCLASS_VECTOR: switch(basetype){ case CG_FLOAT: ctype = LUXI_CLASS_FLOAT; read = cgGetParameterValuefc(cgparam,4,(float*)vector); break; case CG_BOOL: ctype = LUXI_CLASS_BOOLEAN; read = cgGetParameterValueic(cgparam,4,vector); break; case CG_INT: ctype = LUXI_CLASS_INT; read = cgGetParameterValueic(cgparam,4,vector); break; default: return 0; } return FunctionPublish_setRet(pstate,read,ctype,(void*)vector[0],ctype,(void*)vector[1],ctype,(void*)vector[2],ctype,(void*)vector[3]); break; case CG_PARAMETERCLASS_MATRIX: if (into){ // get matrix first if (!FunctionPublish_getNArg(pstate,1,LUXI_CLASS_MATRIX44,(void*)&ref) || !Reference_get(ref,matrix)) return FunctionPublish_returnError(pstate,"1 matrix4x4 required"); } else{ // create matrix matrix = PubMatrix4x4_alloc(); ref = Reference_new(LUXI_CLASS_MATRIX44,matrix); Reference_makeVolatile(ref); } cgGetMatrixParameterfc(cgparam,matrix); return FunctionPublish_returnType(pstate,LUXI_CLASS_MATRIX44,REF2VOID(ref)); break; case CG_PARAMETERCLASS_ARRAY: ctype = basetype == CG_FLOAT ? LUXI_CLASS_FLOATARRAY : LUXI_CLASS_INTARRAY; size = cgGetParameterColumns(cgparam)*cgGetParameterRows(cgparam)*cgGetArrayTotalSize(cgparam); if (into){ // get array first if (FunctionPublish_getArgOffset(pstate,1,3,ctype,(void*)&ref,LUXI_CLASS_INT,(void*)&offset)<1 || !Reference_get(ref,starray) || offset+size > starray->count) return FunctionPublish_returnError(pstate,"1 staticarray [1 int] required (with enough space)"); } else{ // create array starray = StaticArray_new(size,ctype,NULL,NULL); } offset = LUX_MIN(offset,(starray->count-1)); read = LUX_MIN(read,(starray->count-offset)); if (ctype == LUXI_CLASS_FLOATARRAY) cgGetParameterValuefc(cgparam,read,starray->floats); else cgGetParameterValueic(cgparam,read,starray->ints); return FunctionPublish_returnType(pstate,ctype,REF2VOID(starray->ref)); } } else { // set lxVector4 vector; switch(classtype){ case CG_PARAMETERCLASS_SCALAR: case CG_PARAMETERCLASS_VECTOR: ctype = basetype == CG_FLOAT ? LUXI_CLASS_FLOAT : LUXI_CLASS_INT; read = FunctionPublish_getArgOffset(pstate,1,n-1,ctype,(void*)&vector[0],ctype,(void*)&vector[1],ctype,(void*)&vector[2],ctype,(void*)&vector[3]); if (read > 0){ switch(basetype){ case CG_FLOAT: cgSetParameterValuefc(cgparam,n-1,vector); return 0; case CG_BOOL: case CG_INT: cgSetParameterValueic(cgparam,n-1,(int*)vector); return 0; default: return 0; } } break; case CG_PARAMETERCLASS_MATRIX: if (!FunctionPublish_getNArg(pstate,1,LUXI_CLASS_MATRIX44,(void*)&ref) || !Reference_get(ref,matrix)) return FunctionPublish_returnError(pstate,"1 matrix4x4 required"); cgSetMatrixParameterfc(cgparam,matrix); return 0; case CG_PARAMETERCLASS_ARRAY: ctype = basetype == CG_FLOAT ? LUXI_CLASS_FLOATARRAY : LUXI_CLASS_INTARRAY; size = cgGetParameterColumns(cgparam)*cgGetParameterRows(cgparam)*cgGetArrayTotalSize(cgparam); if (FunctionPublish_getArgOffset(pstate,1,3,ctype,(void*)&ref,LUXI_CLASS_INT,(void*)&offset) || !Reference_get(ref,starray) || offset+size > starray->count) return FunctionPublish_returnError(pstate,"1 staticarray [2 ints] required, with enough space"); offset = LUX_MIN(offset,(starray->count-1)); if (ctype == LUXI_CLASS_FLOATARRAY) cgSetParameterValuefc(cgparam,size,&starray->floats[offset]); else cgSetParameterValueic(cgparam,size,&starray->ints[offset]); return 0; default: return 0; } } } case PCG_SIZES: return FunctionPublish_setRet(pstate,3,LUXI_CLASS_INT,(void*)cgGetParameterColumns(cgparam),LUXI_CLASS_INT,(void*)cgGetParameterRows(cgparam),LUXI_CLASS_INT,(void*)cgGetArrayTotalSize(cgparam)); default: break; } return 0; }