//--------------------------------------------------------------------- void GLSLProgramManagerCommon::extractUniforms(GLuint programObject, const GpuConstantDefinitionMap* vertexConstantDefs, const GpuConstantDefinitionMap* geometryConstantDefs, const GpuConstantDefinitionMap* fragmentConstantDefs, const GpuConstantDefinitionMap* hullConstantDefs, const GpuConstantDefinitionMap* domainConstantDefs, const GpuConstantDefinitionMap* computeConstantDefs, GLUniformReferenceList& list, GLUniformBufferList& sharedList) { // Scan through the active uniforms and add them to the reference list GLint uniformCount = 0; #define uniformLength 200 // GLint uniformLength = 0; // glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &uniformLength); char uniformName[uniformLength]; GLUniformReference newGLUniformReference; // Get the number of active uniforms OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); // Loop over each of the active uniforms, and add them to the reference container // only do this for user defined uniforms, ignore built in gl state uniforms for (int index = 0; index < uniformCount; index++) { GLint arraySize; GLenum glType; OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, uniformLength, NULL, &arraySize, &glType, uniformName)); // Don't add built in uniforms OGRE_CHECK_GL_ERROR(newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName)); if (newGLUniformReference.mLocation >= 0) { // User defined uniform found, add it to the reference list String paramName = String( uniformName ); // Current ATI drivers (Catalyst 7.2 and earlier) and older NVidia drivers will include all array elements as uniforms but we only want the root array name and location // Also note that ATI Catalyst 6.8 to 7.2 there is a bug with glUniform that does not allow you to update a uniform array past the first uniform array element // ie you can't start updating an array starting at element 1, must always be element 0. // If the uniform name has a "[" in it then its an array element uniform. String::size_type arrayStart = paramName.find("["); if (arrayStart != String::npos) { // if not the first array element then skip it and continue to the next uniform if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; paramName = paramName.substr(0, arrayStart); } // Find out which params object this comes from bool foundSource = completeParamSource(paramName, vertexConstantDefs, geometryConstantDefs, fragmentConstantDefs, hullConstantDefs, domainConstantDefs, computeConstantDefs, newGLUniformReference); // Only add this parameter if we found the source if (foundSource) { assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize && "GL doesn't agree with our array size!"); list.push_back(newGLUniformReference); } // Don't bother adding individual array params, they will be // picked up in the 'parent' parameter can copied all at once // anyway, individual indexes are only needed for lookup from // user params } // end if } // end for // Now deal with uniform blocks GLint blockCount = 0; OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount)); for (int index = 0; index < blockCount; index++) { OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockName(programObject, index, uniformLength, NULL, uniformName)); GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); GLint blockSize, blockBinding; OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize)); OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_BINDING, &blockBinding)); HardwareUniformBufferSharedPtr newUniformBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false, uniformName); GL3PlusHardwareUniformBuffer* hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(newUniformBuffer.get()); hwGlBuffer->setGLBufferBinding(blockBinding); sharedList.push_back(newUniformBuffer); } }
//--------------------------------------------------------------------- void GLSLESProgramManagerCommon::extractUniforms(GLuint programObject, const GpuConstantDefinitionMap* vertexConstantDefs, const GpuConstantDefinitionMap* fragmentConstantDefs, GLUniformReferenceList& list, GLUniformBufferList& sharedList) { // Scan through the active uniforms and add them to the reference list GLint uniformCount = 0; GLint maxLength = 0; char* uniformName = NULL; #define uniformLength 200 OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); // If the max length of active uniforms is 0, then there are 0 active. // There won't be any to extract so we can return. if(maxLength == 0) return; uniformName = new char[maxLength + 1]; GLUniformReference newGLUniformReference; // Get the number of active uniforms OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORMS, &uniformCount)); // Loop over each of the active uniforms, and add them to the reference container // only do this for user defined uniforms, ignore built in gl state uniforms for (GLuint index = 0; index < (GLuint)uniformCount; index++) { GLint arraySize = 0; GLenum glType = GL_NONE; OGRE_CHECK_GL_ERROR(glGetActiveUniform(programObject, index, maxLength, NULL, &arraySize, &glType, uniformName)); // Don't add built in uniforms newGLUniformReference.mLocation = glGetUniformLocation(programObject, uniformName); if (newGLUniformReference.mLocation >= 0) { // User defined uniform found, add it to the reference list String paramName = String( uniformName ); // If the uniform name has a "[" in it then its an array element uniform. String::size_type arrayStart = paramName.find("["); if (arrayStart != String::npos) { // If not the first array element then skip it and continue to the next uniform if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0) continue; paramName = paramName.substr(0, arrayStart); } // Find out which params object this comes from bool foundSource = completeParamSource(paramName, vertexConstantDefs, fragmentConstantDefs, newGLUniformReference); // Only add this parameter if we found the source if (foundSource) { assert(size_t (arraySize) == newGLUniformReference.mConstantDef->arraySize && "GL doesn't agree with our array size!"); list.push_back(newGLUniformReference); } // Don't bother adding individual array params, they will be // picked up in the 'parent' parameter can copied all at once // anyway, individual indexes are only needed for lookup from // user params } // end if } // end for if( uniformName != NULL ) { delete[] uniformName; } #if OGRE_NO_GLES3_SUPPORT == 0 // Now deal with uniform blocks GLint blockCount = 0; OGRE_CHECK_GL_ERROR(glGetProgramiv(programObject, GL_ACTIVE_UNIFORM_BLOCKS, &blockCount)); for (int index = 0; index < blockCount; index++) { OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockName(programObject, index, uniformLength, NULL, uniformName)); GpuSharedParametersPtr blockSharedParams = GpuProgramManager::getSingleton().getSharedParameters(uniformName); GLint blockSize, blockBinding; OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize)); OGRE_CHECK_GL_ERROR(glGetActiveUniformBlockiv(programObject, index, GL_UNIFORM_BLOCK_BINDING, &blockBinding)); HardwareUniformBufferSharedPtr newUniformBuffer = HardwareBufferManager::getSingleton().createUniformBuffer(blockSize, HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false, uniformName); GLES2HardwareUniformBuffer* hwGlBuffer = static_cast<GLES2HardwareUniformBuffer*>(newUniformBuffer.get()); hwGlBuffer->setGLBufferBinding(blockBinding); sharedList.push_back(newUniformBuffer); } #endif }