1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2013 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 29 #include "OgreGLSLProgramPipeline.h" 30 #include "OgreStringConverter.h" 31 #include "OgreGLSLGpuProgram.h" 32 #include "OgreGLSLProgram.h" 33 #include "OgreGLSLProgramPipelineManager.h" 34 #include "OgreGpuProgramManager.h" 35 #include "OgreGL3PlusUtil.h" 36 #include "OgreLogManager.h" 37 38 namespace Ogre 39 { GLSLProgramPipeline(GLSLGpuProgram * vertexProgram,GLSLGpuProgram * geometryProgram,GLSLGpuProgram * fragmentProgram,GLSLGpuProgram * hullProgram,GLSLGpuProgram * domainProgram,GLSLGpuProgram * computeProgram)40 GLSLProgramPipeline::GLSLProgramPipeline(GLSLGpuProgram* vertexProgram, GLSLGpuProgram* geometryProgram, GLSLGpuProgram* fragmentProgram, GLSLGpuProgram* hullProgram, GLSLGpuProgram* domainProgram, GLSLGpuProgram* computeProgram) : 41 GLSLProgramCommon(vertexProgram, geometryProgram, fragmentProgram, hullProgram, domainProgram, computeProgram) { } 42 ~GLSLProgramPipeline()43 GLSLProgramPipeline::~GLSLProgramPipeline() 44 { 45 OGRE_CHECK_GL_ERROR(glDeleteProgramPipelines(1, &mGLProgramPipelineHandle)); 46 } 47 compileAndLink()48 void GLSLProgramPipeline::compileAndLink() 49 { 50 OGRE_CHECK_GL_ERROR(glGenProgramPipelines(1, &mGLProgramPipelineHandle)); 51 OGRE_CHECK_GL_ERROR(glBindProgramPipeline(mGLProgramPipelineHandle)); 52 53 mVertexArrayObject = new GL3PlusVertexArrayObject(); 54 mVertexArrayObject->bind(); 55 56 compileIndividualProgram(mVertexProgram); 57 compileIndividualProgram(mFragmentProgram); 58 compileIndividualProgram(mGeometryProgram); 59 compileIndividualProgram(mDomainProgram); 60 compileIndividualProgram(mHullProgram); 61 compileIndividualProgram(mComputeProgram); 62 63 if(mLinked) 64 { 65 if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() ) 66 { 67 // Add to the microcode to the cache 68 String name; 69 name = getCombinedName(); 70 71 // Get buffer size 72 GLint binaryLength = 0; 73 74 OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramPipelineHandle, GL_PROGRAM_BINARY_LENGTH, &binaryLength)); 75 76 // Create microcode 77 GpuProgramManager::Microcode newMicrocode = 78 GpuProgramManager::getSingleton().createMicrocode(binaryLength + sizeof(GLenum)); 79 80 // Get binary 81 OGRE_CHECK_GL_ERROR(glGetProgramBinary(mGLProgramPipelineHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum))); 82 83 // Add to the microcode to the cache 84 GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode); 85 } 86 if(mVertexProgram && mVertexProgram->isLinked()) 87 { 88 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_VERTEX_SHADER_BIT, mVertexProgram->getGLSLProgram()->getGLProgramHandle())); 89 } 90 if(mFragmentProgram && mFragmentProgram->isLinked()) 91 { 92 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_FRAGMENT_SHADER_BIT, mFragmentProgram->getGLSLProgram()->getGLProgramHandle())); 93 } 94 if(mGeometryProgram && mGeometryProgram->isLinked()) 95 { 96 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_GEOMETRY_SHADER_BIT, mGeometryProgram->getGLSLProgram()->getGLProgramHandle())); 97 } 98 if(mDomainProgram && mDomainProgram->isLinked()) 99 { 100 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_TESS_EVALUATION_SHADER_BIT, mDomainProgram->getGLSLProgram()->getGLProgramHandle())); 101 } 102 if(mHullProgram && mHullProgram->isLinked()) 103 { 104 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_TESS_CONTROL_SHADER_BIT, mHullProgram->getGLSLProgram()->getGLProgramHandle())); 105 } 106 if(mComputeProgram && mComputeProgram->isLinked()) 107 { 108 OGRE_CHECK_GL_ERROR(glUseProgramStages(mGLProgramPipelineHandle, GL_COMPUTE_SHADER_BIT, mComputeProgram->getGLSLProgram()->getGLProgramHandle())); 109 } 110 111 // Validate pipeline 112 logObjectInfo( getCombinedName() + String("GLSL program pipeline result : "), mGLProgramPipelineHandle ); 113 114 // if(getGLSupport()->checkExtension("GL_KHR_debug") || gl3wIsSupported(4, 3)) 115 // glObjectLabel(GL_PROGRAM_PIPELINE, mGLProgramPipelineHandle, 0, 116 // (mVertexProgram->getName() + "/" + mFragmentProgram->getName()).c_str()); 117 } 118 } 119 compileIndividualProgram(GLSLGpuProgram * program)120 void GLSLProgramPipeline::compileIndividualProgram(GLSLGpuProgram *program) 121 { 122 GLint linkStatus = 0; 123 // Compile and attach program 124 if(program && !program->isLinked()) 125 { 126 try 127 { 128 program->getGLSLProgram()->compile(true); 129 } 130 catch (Exception& e) 131 { 132 LogManager::getSingleton().stream() << e.getDescription(); 133 mTriedToLinkAndFailed = true; 134 return; 135 } 136 GLuint programHandle = program->getGLSLProgram()->getGLProgramHandle(); 137 OGRE_CHECK_GL_ERROR(glProgramParameteri(programHandle, GL_PROGRAM_SEPARABLE, GL_TRUE)); 138 program->getGLSLProgram()->attachToProgramObject(programHandle); 139 OGRE_CHECK_GL_ERROR(glLinkProgram(programHandle)); 140 OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus)); 141 142 program->setLinked(linkStatus); 143 mLinked = linkStatus; 144 145 mTriedToLinkAndFailed = !linkStatus; 146 147 logObjectInfo( getCombinedName() + String("GLSL program result : "), programHandle ); 148 149 if(program->getType() == GPT_VERTEX_PROGRAM) 150 setSkeletalAnimationIncluded(program->isSkeletalAnimationIncluded()); 151 } 152 } 153 _useProgram(void)154 void GLSLProgramPipeline::_useProgram(void) 155 { 156 if (mLinked) 157 { 158 OGRE_CHECK_GL_ERROR(glBindProgramPipeline(mGLProgramPipelineHandle)); 159 } 160 } 161 162 //----------------------------------------------------------------------- getAttributeIndex(VertexElementSemantic semantic,uint index)163 GLint GLSLProgramPipeline::getAttributeIndex(VertexElementSemantic semantic, uint index) 164 { 165 GLint res = mCustomAttributesIndexes[semantic-1][index]; 166 if (res == NULL_CUSTOM_ATTRIBUTES_INDEX) 167 { 168 GLuint handle = mVertexProgram->getGLSLProgram()->getGLProgramHandle(); 169 const char * attString = getAttributeSemanticString(semantic); 170 GLint attrib; 171 OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, attString)); 172 173 // Sadly position is a special case 174 if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION) 175 { 176 OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, "position")); 177 } 178 179 // For uv and other case the index is a part of the name 180 if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX) 181 { 182 String attStringWithSemantic = String(attString) + StringConverter::toString(index); 183 OGRE_CHECK_GL_ERROR(attrib = glGetAttribLocation(handle, attStringWithSemantic.c_str())); 184 } 185 186 // Update mCustomAttributesIndexes with the index we found (or didn't find) 187 mCustomAttributesIndexes[semantic-1][index] = attrib; 188 res = attrib; 189 } 190 191 return res; 192 } 193 194 //----------------------------------------------------------------------- activate(void)195 void GLSLProgramPipeline::activate(void) 196 { 197 if (!mLinked && !mTriedToLinkAndFailed) 198 { 199 if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() && 200 GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) ) 201 { 202 getMicrocodeFromCache(); 203 } 204 else 205 { 206 compileAndLink(); 207 } 208 209 extractLayoutQualifiers(); 210 211 buildGLUniformReferences(); 212 } 213 214 _useProgram(); 215 } 216 217 //----------------------------------------------------------------------- updateUniformBlocks(GpuProgramParametersSharedPtr params,uint16 mask,GpuProgramType fromProgType)218 void GLSLProgramPipeline::updateUniformBlocks(GpuProgramParametersSharedPtr params, 219 uint16 mask, GpuProgramType fromProgType) 220 { 221 // Iterate through the list of uniform buffers and update them as needed 222 GLUniformBufferIterator currentBuffer = mGLUniformBufferReferences.begin(); 223 GLUniformBufferIterator endBuffer = mGLUniformBufferReferences.end(); 224 225 const GpuProgramParameters::GpuSharedParamUsageList& sharedParams = params->getSharedParameters(); 226 227 GpuProgramParameters::GpuSharedParamUsageList::const_iterator it, end = sharedParams.end(); 228 for (it = sharedParams.begin(); it != end; ++it) 229 { 230 for (;currentBuffer != endBuffer; ++currentBuffer) 231 { 232 GL3PlusHardwareUniformBuffer* hwGlBuffer = static_cast<GL3PlusHardwareUniformBuffer*>(currentBuffer->get()); 233 GpuSharedParametersPtr paramsPtr = it->getSharedParams(); 234 235 // Block name is stored in mSharedParams->mName of GpuSharedParamUsageList items 236 GLint UniformTransform; 237 OGRE_CHECK_GL_ERROR(UniformTransform = glGetUniformBlockIndex(mGLProgramHandle, it->getName().c_str())); 238 OGRE_CHECK_GL_ERROR(glUniformBlockBinding(mGLProgramHandle, UniformTransform, hwGlBuffer->getGLBufferBinding())); 239 240 hwGlBuffer->writeData(0, hwGlBuffer->getSizeInBytes(), ¶msPtr->getFloatConstantList().front()); 241 } 242 } 243 } 244 245 //----------------------------------------------------------------------- buildGLUniformReferences(void)246 void GLSLProgramPipeline::buildGLUniformReferences(void) 247 { 248 if (!mUniformRefsBuilt) 249 { 250 const GpuConstantDefinitionMap* vertParams = 0; 251 const GpuConstantDefinitionMap* fragParams = 0; 252 const GpuConstantDefinitionMap* geomParams = 0; 253 const GpuConstantDefinitionMap* hullParams = 0; 254 const GpuConstantDefinitionMap* domainParams = 0; 255 const GpuConstantDefinitionMap* computeParams = 0; 256 if (mVertexProgram) 257 { 258 vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map); 259 GLSLProgramPipelineManager::getSingleton().extractUniforms(mVertexProgram->getGLSLProgram()->getGLProgramHandle(), 260 vertParams, NULL, NULL, NULL, NULL, NULL, mGLUniformReferences, mGLUniformBufferReferences); 261 } 262 if (mGeometryProgram) 263 { 264 geomParams = &(mGeometryProgram->getGLSLProgram()->getConstantDefinitions().map); 265 GLSLProgramPipelineManager::getSingleton().extractUniforms(mGeometryProgram->getGLSLProgram()->getGLProgramHandle(), 266 NULL, geomParams, NULL, NULL, NULL, NULL, mGLUniformReferences, mGLUniformBufferReferences); 267 } 268 if (mFragmentProgram) 269 { 270 fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map); 271 GLSLProgramPipelineManager::getSingleton().extractUniforms(mFragmentProgram->getGLSLProgram()->getGLProgramHandle(), 272 NULL, NULL, fragParams, NULL, NULL, NULL, mGLUniformReferences, mGLUniformBufferReferences); 273 } 274 if (mHullProgram) 275 { 276 hullParams = &(mHullProgram->getGLSLProgram()->getConstantDefinitions().map); 277 GLSLProgramPipelineManager::getSingleton().extractUniforms(mHullProgram->getGLSLProgram()->getGLProgramHandle(), 278 NULL, NULL, NULL, hullParams, NULL, NULL, mGLUniformReferences, mGLUniformBufferReferences); 279 } 280 if (mDomainProgram) 281 { 282 domainParams = &(mDomainProgram->getGLSLProgram()->getConstantDefinitions().map); 283 GLSLProgramPipelineManager::getSingleton().extractUniforms(mDomainProgram->getGLSLProgram()->getGLProgramHandle(), 284 NULL, NULL, NULL, NULL, domainParams, NULL, mGLUniformReferences, mGLUniformBufferReferences); 285 } 286 if (mComputeProgram) 287 { 288 computeParams = &(mComputeProgram->getGLSLProgram()->getConstantDefinitions().map); 289 GLSLProgramPipelineManager::getSingleton().extractUniforms(mComputeProgram->getGLSLProgram()->getGLProgramHandle(), 290 NULL, NULL, NULL, NULL, NULL, computeParams, mGLUniformReferences, mGLUniformBufferReferences); 291 } 292 293 mUniformRefsBuilt = true; 294 } 295 } 296 297 //----------------------------------------------------------------------- updateUniforms(GpuProgramParametersSharedPtr params,uint16 mask,GpuProgramType fromProgType)298 void GLSLProgramPipeline::updateUniforms(GpuProgramParametersSharedPtr params, 299 uint16 mask, GpuProgramType fromProgType) 300 { 301 // Iterate through uniform reference list and update uniform values 302 GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); 303 GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); 304 305 // determine if we need to transpose matrices when binding 306 int transpose = GL_TRUE; 307 if ((fromProgType == GPT_FRAGMENT_PROGRAM && mVertexProgram && (!mVertexProgram->getGLSLProgram()->getColumnMajorMatrices())) || 308 (fromProgType == GPT_VERTEX_PROGRAM && mFragmentProgram && (!mFragmentProgram->getGLSLProgram()->getColumnMajorMatrices())) || 309 (fromProgType == GPT_GEOMETRY_PROGRAM && mGeometryProgram && (!mGeometryProgram->getGLSLProgram()->getColumnMajorMatrices())) || 310 (fromProgType == GPT_HULL_PROGRAM && mHullProgram && (!mHullProgram->getGLSLProgram()->getColumnMajorMatrices())) || 311 (fromProgType == GPT_DOMAIN_PROGRAM && mDomainProgram && (!mDomainProgram->getGLSLProgram()->getColumnMajorMatrices())) || 312 (fromProgType == GPT_COMPUTE_PROGRAM && mComputeProgram && (!mComputeProgram->getGLSLProgram()->getColumnMajorMatrices()))) 313 { 314 transpose = GL_FALSE; 315 } 316 317 GLuint progID = 0; 318 if(fromProgType == GPT_VERTEX_PROGRAM) 319 { 320 progID = mVertexProgram->getGLSLProgram()->getGLProgramHandle(); 321 } 322 else if(fromProgType == GPT_FRAGMENT_PROGRAM) 323 { 324 progID = mFragmentProgram->getGLSLProgram()->getGLProgramHandle(); 325 } 326 else if(fromProgType == GPT_GEOMETRY_PROGRAM) 327 { 328 progID = mGeometryProgram->getGLSLProgram()->getGLProgramHandle(); 329 } 330 else if(fromProgType == GPT_HULL_PROGRAM) 331 { 332 progID = mHullProgram->getGLSLProgram()->getGLProgramHandle(); 333 } 334 else if(fromProgType == GPT_DOMAIN_PROGRAM) 335 { 336 progID = mDomainProgram->getGLSLProgram()->getGLProgramHandle(); 337 } 338 else if(fromProgType == GPT_COMPUTE_PROGRAM) 339 { 340 progID = mComputeProgram->getGLSLProgram()->getGLProgramHandle(); 341 } 342 343 for (;currentUniform != endUniform; ++currentUniform) 344 { 345 // Only pull values from buffer it's supposed to be in (vertex or fragment) 346 // This method will be called twice, once for vertex program params, 347 // and once for fragment program params. 348 if (fromProgType == currentUniform->mSourceProgType) 349 { 350 const GpuConstantDefinition* def = currentUniform->mConstantDef; 351 if (def->variability & mask) 352 { 353 GLsizei glArraySize = (GLsizei)def->arraySize; 354 355 // Get the index in the parameter real list 356 switch (def->constType) 357 { 358 case GCT_FLOAT1: 359 OGRE_CHECK_GL_ERROR(glProgramUniform1fv(progID, currentUniform->mLocation, glArraySize, 360 params->getFloatPointer(def->physicalIndex))); 361 break; 362 case GCT_FLOAT2: 363 OGRE_CHECK_GL_ERROR(glProgramUniform2fv(progID, currentUniform->mLocation, glArraySize, 364 params->getFloatPointer(def->physicalIndex))); 365 break; 366 case GCT_FLOAT3: 367 OGRE_CHECK_GL_ERROR(glProgramUniform3fv(progID, currentUniform->mLocation, glArraySize, 368 params->getFloatPointer(def->physicalIndex))); 369 break; 370 case GCT_FLOAT4: 371 OGRE_CHECK_GL_ERROR(glProgramUniform4fv(progID, currentUniform->mLocation, glArraySize, 372 params->getFloatPointer(def->physicalIndex))); 373 break; 374 case GCT_MATRIX_2X2: 375 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2fv(progID, currentUniform->mLocation, glArraySize, 376 transpose, params->getFloatPointer(def->physicalIndex))); 377 break; 378 case GCT_MATRIX_3X3: 379 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3fv(progID, currentUniform->mLocation, glArraySize, 380 transpose, params->getFloatPointer(def->physicalIndex))); 381 break; 382 case GCT_MATRIX_4X4: 383 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4fv(progID, currentUniform->mLocation, glArraySize, 384 transpose, params->getFloatPointer(def->physicalIndex))); 385 break; 386 case GCT_INT1: 387 OGRE_CHECK_GL_ERROR(glProgramUniform1iv(progID, currentUniform->mLocation, glArraySize, 388 params->getIntPointer(def->physicalIndex))); 389 break; 390 case GCT_INT2: 391 OGRE_CHECK_GL_ERROR(glProgramUniform2iv(progID, currentUniform->mLocation, glArraySize, 392 params->getIntPointer(def->physicalIndex))); 393 break; 394 case GCT_INT3: 395 OGRE_CHECK_GL_ERROR(glProgramUniform3iv(progID, currentUniform->mLocation, glArraySize, 396 params->getIntPointer(def->physicalIndex))); 397 break; 398 case GCT_INT4: 399 OGRE_CHECK_GL_ERROR(glProgramUniform4iv(progID, currentUniform->mLocation, glArraySize, 400 params->getIntPointer(def->physicalIndex))); 401 break; 402 case GCT_MATRIX_2X3: 403 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2x3fv(progID, currentUniform->mLocation, glArraySize, 404 transpose, params->getFloatPointer(def->physicalIndex))); 405 break; 406 case GCT_MATRIX_2X4: 407 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2x4fv(progID, currentUniform->mLocation, glArraySize, 408 transpose, params->getFloatPointer(def->physicalIndex))); 409 break; 410 case GCT_MATRIX_3X2: 411 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3x2fv(progID, currentUniform->mLocation, glArraySize, 412 transpose, params->getFloatPointer(def->physicalIndex))); 413 break; 414 case GCT_MATRIX_3X4: 415 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3x4fv(progID, currentUniform->mLocation, glArraySize, 416 transpose, params->getFloatPointer(def->physicalIndex))); 417 break; 418 case GCT_MATRIX_4X2: 419 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4x2fv(progID, currentUniform->mLocation, glArraySize, 420 transpose, params->getFloatPointer(def->physicalIndex))); 421 break; 422 case GCT_MATRIX_4X3: 423 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4x3fv(progID, currentUniform->mLocation, glArraySize, 424 transpose, params->getFloatPointer(def->physicalIndex))); 425 break; 426 case GCT_DOUBLE1: 427 OGRE_CHECK_GL_ERROR(glProgramUniform1dv(progID, currentUniform->mLocation, glArraySize, 428 params->getDoublePointer(def->physicalIndex))); 429 break; 430 case GCT_DOUBLE2: 431 OGRE_CHECK_GL_ERROR(glProgramUniform2dv(progID, currentUniform->mLocation, glArraySize, 432 params->getDoublePointer(def->physicalIndex))); 433 break; 434 case GCT_DOUBLE3: 435 OGRE_CHECK_GL_ERROR(glProgramUniform3dv(progID, currentUniform->mLocation, glArraySize, 436 params->getDoublePointer(def->physicalIndex))); 437 break; 438 case GCT_DOUBLE4: 439 OGRE_CHECK_GL_ERROR(glProgramUniform4dv(progID, currentUniform->mLocation, glArraySize, 440 params->getDoublePointer(def->physicalIndex))); 441 break; 442 case GCT_MATRIX_DOUBLE_2X2: 443 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2dv(progID, currentUniform->mLocation, glArraySize, 444 transpose, params->getDoublePointer(def->physicalIndex))); 445 break; 446 case GCT_MATRIX_DOUBLE_3X3: 447 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3dv(progID, currentUniform->mLocation, glArraySize, 448 transpose, params->getDoublePointer(def->physicalIndex))); 449 break; 450 case GCT_MATRIX_DOUBLE_4X4: 451 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4dv(progID, currentUniform->mLocation, glArraySize, 452 transpose, params->getDoublePointer(def->physicalIndex))); 453 break; 454 case GCT_MATRIX_DOUBLE_2X3: 455 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2x3dv(progID, currentUniform->mLocation, glArraySize, 456 transpose, params->getDoublePointer(def->physicalIndex))); 457 break; 458 case GCT_MATRIX_DOUBLE_2X4: 459 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix2x4dv(progID, currentUniform->mLocation, glArraySize, 460 transpose, params->getDoublePointer(def->physicalIndex))); 461 break; 462 case GCT_MATRIX_DOUBLE_3X2: 463 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3x2dv(progID, currentUniform->mLocation, glArraySize, 464 transpose, params->getDoublePointer(def->physicalIndex))); 465 break; 466 case GCT_MATRIX_DOUBLE_3X4: 467 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix3x4dv(progID, currentUniform->mLocation, glArraySize, 468 transpose, params->getDoublePointer(def->physicalIndex))); 469 break; 470 case GCT_MATRIX_DOUBLE_4X2: 471 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4x2dv(progID, currentUniform->mLocation, glArraySize, 472 transpose, params->getDoublePointer(def->physicalIndex))); 473 break; 474 case GCT_MATRIX_DOUBLE_4X3: 475 OGRE_CHECK_GL_ERROR(glProgramUniformMatrix4x3dv(progID, currentUniform->mLocation, glArraySize, 476 transpose, params->getDoublePointer(def->physicalIndex))); 477 break; 478 case GCT_SAMPLER1D: 479 case GCT_SAMPLER1DSHADOW: 480 case GCT_SAMPLER2D: 481 case GCT_SAMPLER2DSHADOW: 482 case GCT_SAMPLER2DARRAY: 483 case GCT_SAMPLER3D: 484 case GCT_SAMPLERCUBE: 485 case GCT_SAMPLERRECT: 486 // Samplers handled like 1-element ints 487 OGRE_CHECK_GL_ERROR(glProgramUniform1iv(progID, currentUniform->mLocation, 1, 488 params->getIntPointer(def->physicalIndex))); 489 break; 490 case GCT_UNKNOWN: 491 case GCT_SUBROUTINE: 492 break; 493 494 } // End switch 495 } // Variability & mask 496 } // fromProgType == currentUniform->mSourceProgType 497 498 } // End for 499 } 500 //----------------------------------------------------------------------- updatePassIterationUniforms(GpuProgramParametersSharedPtr params)501 void GLSLProgramPipeline::updatePassIterationUniforms(GpuProgramParametersSharedPtr params) 502 { 503 if (params->hasPassIterationNumber()) 504 { 505 size_t index = params->getPassIterationNumberIndex(); 506 507 GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin(); 508 GLUniformReferenceIterator endUniform = mGLUniformReferences.end(); 509 510 // Need to find the uniform that matches the multi pass entry 511 for (;currentUniform != endUniform; ++currentUniform) 512 { 513 // Get the index in the parameter real list 514 if (index == currentUniform->mConstantDef->physicalIndex) 515 { 516 GLuint progID = 0; 517 if (mVertexProgram && currentUniform->mSourceProgType == GPT_VERTEX_PROGRAM) 518 { 519 progID = mVertexProgram->getGLSLProgram()->getGLProgramHandle(); 520 } 521 522 if (mFragmentProgram && currentUniform->mSourceProgType == GPT_FRAGMENT_PROGRAM) 523 { 524 progID = mFragmentProgram->getGLSLProgram()->getGLProgramHandle(); 525 } 526 527 if (mGeometryProgram && currentUniform->mSourceProgType == GPT_GEOMETRY_PROGRAM) 528 { 529 progID = mGeometryProgram->getGLSLProgram()->getGLProgramHandle(); 530 } 531 532 if (mDomainProgram && currentUniform->mSourceProgType == GPT_DOMAIN_PROGRAM) 533 { 534 progID = mDomainProgram->getGLSLProgram()->getGLProgramHandle(); 535 } 536 537 if (mHullProgram && currentUniform->mSourceProgType == GPT_HULL_PROGRAM) 538 { 539 progID = mHullProgram->getGLSLProgram()->getGLProgramHandle(); 540 } 541 542 if (mComputeProgram && currentUniform->mSourceProgType == GPT_COMPUTE_PROGRAM) 543 { 544 progID = mComputeProgram->getGLSLProgram()->getGLProgramHandle(); 545 } 546 547 OGRE_CHECK_GL_ERROR(glProgramUniform1fv(progID, currentUniform->mLocation, 1, params->getFloatPointer(index))); 548 549 // There will only be one multipass entry 550 return; 551 } 552 } 553 } 554 } 555 } 556