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 "OgreGLSLGpuProgram.h" 30 #include "OgreGLSLProgram.h" 31 #include "OgreGLSLLinkProgramManager.h" 32 #include "OgreGLSLProgramPipelineManager.h" 33 #include "OgreRoot.h" 34 35 namespace Ogre { 36 37 GLuint GLSLGpuProgram::mVertexShaderCount = 0; 38 GLuint GLSLGpuProgram::mFragmentShaderCount = 0; 39 GLuint GLSLGpuProgram::mGeometryShaderCount = 0; 40 GLuint GLSLGpuProgram::mHullShaderCount = 0; 41 GLuint GLSLGpuProgram::mDomainShaderCount = 0; 42 GLuint GLSLGpuProgram::mComputeShaderCount = 0; 43 //----------------------------------------------------------------------------- GLSLGpuProgram(GLSLProgram * parent)44 GLSLGpuProgram::GLSLGpuProgram(GLSLProgram* parent) : 45 GL3PlusGpuProgram(parent->getCreator(), parent->getName(), parent->getHandle(), 46 parent->getGroup(), false, 0), mGLSLProgram(parent) 47 { 48 mType = parent->getType(); 49 mSyntaxCode = "glsl" + StringConverter::toString(Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion()); 50 51 mLinked = 0; 52 53 if (parent->getType() == GPT_VERTEX_PROGRAM) 54 { 55 mProgramID = ++mVertexShaderCount; 56 } 57 else if (parent->getType() == GPT_FRAGMENT_PROGRAM) 58 { 59 mProgramID = ++mFragmentShaderCount; 60 } 61 else if (parent->getType() == GPT_GEOMETRY_PROGRAM) 62 { 63 mProgramID = ++mGeometryShaderCount; 64 } 65 else if (parent->getType() == GPT_HULL_PROGRAM) 66 { 67 mProgramID = ++mHullShaderCount; 68 } 69 else if (parent->getType() == GPT_COMPUTE_PROGRAM) 70 { 71 mProgramID = ++mComputeShaderCount; 72 } 73 else 74 { 75 mProgramID = ++mDomainShaderCount; 76 } 77 78 // Transfer skeletal animation status from parent 79 mSkeletalAnimation = mGLSLProgram->isSkeletalAnimationIncluded(); 80 // There is nothing to load 81 mLoadFromFile = false; 82 } 83 //----------------------------------------------------------------------- ~GLSLGpuProgram()84 GLSLGpuProgram::~GLSLGpuProgram() 85 { 86 // Have to call this here rather than in Resource destructor 87 // since calling virtual methods in base destructors causes crash 88 unload(); 89 } 90 //----------------------------------------------------------------------------- loadImpl(void)91 void GLSLGpuProgram::loadImpl(void) 92 { 93 // nothing to load 94 } 95 96 //----------------------------------------------------------------------------- unloadImpl(void)97 void GLSLGpuProgram::unloadImpl(void) 98 { 99 // nothing to unload 100 } 101 102 //----------------------------------------------------------------------------- loadFromSource(void)103 void GLSLGpuProgram::loadFromSource(void) 104 { 105 // nothing to load 106 } 107 108 //----------------------------------------------------------------------------- bindProgram(void)109 void GLSLGpuProgram::bindProgram(void) 110 { 111 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 112 { 113 // Tell the Program Pipeline Manager what pipeline is to become active 114 switch (mType) 115 { 116 case GPT_VERTEX_PROGRAM: 117 GLSLProgramPipelineManager::getSingleton().setActiveVertexLinkProgram( this ); 118 break; 119 case GPT_FRAGMENT_PROGRAM: 120 GLSLProgramPipelineManager::getSingleton().setActiveFragmentLinkProgram( this ); 121 break; 122 case GPT_GEOMETRY_PROGRAM: 123 GLSLProgramPipelineManager::getSingleton().setActiveGeometryLinkProgram( this ); 124 break; 125 case GPT_HULL_PROGRAM: 126 GLSLProgramPipelineManager::getSingleton().setActiveTessHullLinkProgram( this ); 127 break; 128 case GPT_DOMAIN_PROGRAM: 129 GLSLProgramPipelineManager::getSingleton().setActiveTessDomainLinkProgram( this ); 130 break; 131 case GPT_COMPUTE_PROGRAM: 132 GLSLProgramPipelineManager::getSingleton().setActiveComputeLinkProgram( this ); 133 default: 134 break; 135 } 136 } 137 else 138 { 139 // Tell the Link Program Manager what shader is to become active 140 switch (mType) 141 { 142 case GPT_VERTEX_PROGRAM: 143 GLSLLinkProgramManager::getSingleton().setActiveVertexShader( this ); 144 break; 145 case GPT_FRAGMENT_PROGRAM: 146 GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( this ); 147 break; 148 case GPT_GEOMETRY_PROGRAM: 149 GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( this ); 150 break; 151 case GPT_HULL_PROGRAM: 152 GLSLLinkProgramManager::getSingleton().setActiveHullShader( this ); 153 break; 154 case GPT_DOMAIN_PROGRAM: 155 GLSLLinkProgramManager::getSingleton().setActiveDomainShader( this ); 156 break; 157 case GPT_COMPUTE_PROGRAM: 158 GLSLLinkProgramManager::getSingleton().setActiveComputeShader( this ); 159 default: 160 break; 161 } 162 } 163 } 164 165 //----------------------------------------------------------------------------- unbindProgram(void)166 void GLSLGpuProgram::unbindProgram(void) 167 { 168 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 169 { 170 // Tell the Program Pipeline Manager what pipeline is to become inactive 171 if (mType == GPT_VERTEX_PROGRAM) 172 { 173 GLSLProgramPipelineManager::getSingleton().setActiveVertexLinkProgram( NULL ); 174 } 175 else if (mType == GPT_GEOMETRY_PROGRAM) 176 { 177 GLSLProgramPipelineManager::getSingleton().setActiveGeometryLinkProgram( NULL ); 178 } 179 else if (mType == GPT_HULL_PROGRAM) 180 { 181 GLSLProgramPipelineManager::getSingleton().setActiveTessHullLinkProgram( NULL ); 182 } 183 else if (mType == GPT_DOMAIN_PROGRAM) 184 { 185 GLSLProgramPipelineManager::getSingleton().setActiveTessDomainLinkProgram( NULL ); 186 } 187 else if (mType == GPT_COMPUTE_PROGRAM) 188 { 189 GLSLProgramPipelineManager::getSingleton().setActiveComputeLinkProgram( NULL ); 190 } 191 else // Its a fragment shader 192 { 193 GLSLProgramPipelineManager::getSingleton().setActiveFragmentLinkProgram( NULL ); 194 } 195 } 196 else 197 { 198 // Tell the Link Program Manager what shader is to become inactive 199 if (mType == GPT_VERTEX_PROGRAM) 200 { 201 GLSLLinkProgramManager::getSingleton().setActiveVertexShader( NULL ); 202 } 203 else if (mType == GPT_GEOMETRY_PROGRAM) 204 { 205 GLSLLinkProgramManager::getSingleton().setActiveGeometryShader( NULL ); 206 } 207 else if (mType == GPT_HULL_PROGRAM) 208 { 209 GLSLLinkProgramManager::getSingleton().setActiveHullShader( NULL ); 210 } 211 else if (mType == GPT_DOMAIN_PROGRAM) 212 { 213 GLSLLinkProgramManager::getSingleton().setActiveDomainShader( NULL ); 214 } 215 else if (mType == GPT_COMPUTE_PROGRAM) 216 { 217 GLSLLinkProgramManager::getSingleton().setActiveComputeShader( NULL ); 218 } 219 else // Its a fragment shader 220 { 221 GLSLLinkProgramManager::getSingleton().setActiveFragmentShader( NULL ); 222 } 223 } 224 } 225 226 //----------------------------------------------------------------------------- bindProgramSharedParameters(GpuProgramParametersSharedPtr params,uint16 mask)227 void GLSLGpuProgram::bindProgramSharedParameters(GpuProgramParametersSharedPtr params, uint16 mask) 228 { 229 // Link can throw exceptions, ignore them at this point 230 try 231 { 232 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 233 { 234 // Activate the program pipeline object 235 GLSLProgramPipeline* programPipeline = GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline(); 236 // Pass on parameters from params to program object uniforms 237 programPipeline->updateUniformBlocks(params, mask, mType); 238 } 239 else 240 { 241 // Activate the link program object 242 GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); 243 // Pass on parameters from params to program object uniforms 244 linkProgram->updateUniformBlocks(params, mask, mType); 245 } 246 } 247 catch (Exception& e) {} 248 } 249 250 //----------------------------------------------------------------------------- bindProgramParameters(GpuProgramParametersSharedPtr params,uint16 mask)251 void GLSLGpuProgram::bindProgramParameters(GpuProgramParametersSharedPtr params, uint16 mask) 252 { 253 // Link can throw exceptions, ignore them at this point 254 try 255 { 256 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 257 { 258 // Activate the program pipeline object 259 GLSLProgramPipeline* programPipeline = GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline(); 260 // Pass on parameters from params to program object uniforms 261 programPipeline->updateUniforms(params, mask, mType); 262 } 263 else 264 { 265 // Activate the link program object 266 GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); 267 // Pass on parameters from params to program object uniforms 268 linkProgram->updateUniforms(params, mask, mType); 269 } 270 } 271 catch (Exception& e) {} 272 } 273 274 //----------------------------------------------------------------------------- bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params)275 void GLSLGpuProgram::bindProgramPassIterationParameters(GpuProgramParametersSharedPtr params) 276 { 277 if(Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_SEPARATE_SHADER_OBJECTS)) 278 { 279 // Activate the program pipeline object 280 GLSLProgramPipeline* programPipeline = GLSLProgramPipelineManager::getSingleton().getActiveProgramPipeline(); 281 // Pass on parameters from params to program object uniforms 282 programPipeline->updatePassIterationUniforms( params ); 283 } 284 else 285 { 286 // Activate the link program object 287 GLSLLinkProgram* linkProgram = GLSLLinkProgramManager::getSingleton().getActiveLinkProgram(); 288 // Pass on parameters from params to program object uniforms 289 linkProgram->updatePassIterationUniforms( params ); 290 } 291 } 292 } 293 294