//-----------------------------------------------------------------------
	void GLSLLinkProgram::updateUniformBlocks(GpuProgramParametersSharedPtr params, 
                                         uint16 mask, GpuProgramType fromProgType)
	{
        // Iterate through the list of uniform buffers and update them as needed
		GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin();
		GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end();

        const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters();

		GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end();
		for (it = sharedParams.begin(); it != end; ++it)
        {
            for (;currentBuffer != endBuffer; ++currentBuffer)
            {
                GL3PlusHardwareUniformBuffer* hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(currentBuffer->get());
                GpuSharedParametersPtr paramsPtr = it->getSharedParams();

                // Block name is stored in mSharedParams->mName of GpuSharedParamUsageList items
                GLint UniformTransform;
                OGRE_CHECK_GL_ERROR(UniformTransform = glGetUniformBlockIndex(mGLProgramHandle, it->getName().c_str()));
                OGRE_CHECK_GL_ERROR(glUniformBlockBinding(mGLProgramHandle, UniformTransform, hwGlBuffer->getGLBufferBinding()));

                hwGlBuffer->writeData(0, hwGlBuffer->getSizeInBytes(), &paramsPtr->getFloatConstantList().front());
            }
        }
	}
    void GLSLSeparableProgram::updateUniformBlocks(GpuProgramParametersSharedPtr params,
                                                   uint16 mask, GpuProgramType fromProgType)
    {
        //TODO Support uniform block arrays - need to figure how to do this via material.

        // Iterate through the list of uniform blocks and update them as needed.
        SharedParamsBufferMap::const_iterator currentPair = mSharedParamsBufferMap.begin();
        SharedParamsBufferMap::const_iterator endPair = mSharedParamsBufferMap.end();

        // const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters();

        // const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters();
        // GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end();

        for (; currentPair != endPair; ++currentPair)
        {
            GpuSharedParametersPtr paramsPtr = currentPair->first;

            //FIXME Possible buffer does not exist if no associated uniform block.
            GL3PlusHardwareUniformBuffer* hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(currentPair->second.get());

            if (!paramsPtr->isDirty()) continue;

            //FIXME does not check if current progrtype, or if shared param is active

            GpuConstantDefinitionIterator parami = paramsPtr->getConstantDefinitionIterator();

            for (int i = 0; parami.current() != parami.end(); parami.moveNext(), i++)
            {
                //String name = parami->;
                //GpuConstantDefinition * param = GpuConstantConstantDefinition(name);

                //const String* name = &parami.current()->first;
                const GpuConstantDefinition* param = &parami.current()->second;

                BaseConstantType baseType = GpuConstantDefinition::getBaseType(param->constType);

                void* dataPtr;

                size_t index =  param->physicalIndex;

                //TODO Maybe move to GpuSharedParams?  Otherwise create bool buffer.
                switch (baseType)
                {
                case BCT_FLOAT:
                    dataPtr = paramsPtr->getFloatPointer(index);
                    break;
                case BCT_INT:
                    dataPtr = paramsPtr->getIntPointer(index);
                    break;
                case BCT_DOUBLE:
                    dataPtr = paramsPtr->getDoublePointer(index);
                    break;
                case BCT_UINT:
                case BCT_BOOL:
                    dataPtr = paramsPtr->getUnsignedIntPointer(index);
                    break;
                case BCT_SAMPLER:
                case BCT_SUBROUTINE:
                    //TODO implement me!
                default:
                    //TODO error handling
                    continue;
                }

                // in bytes
                size_t length = param->arraySize * param->elementSize * 4;
                size_t offset = hwGlBuffer->mBufferParamsLayout.offsets[i];
                hwGlBuffer->writeData(offset, length, dataPtr);
            }

            paramsPtr->_markClean();
        }
    }