00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://ogre.sourceforge.net/ 00006 00007 Copyright © 2000-2003 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 #include "OgreStableHeaders.h" 00026 #include "OgreGpuProgram.h" 00027 #include "OgreGpuProgramManager.h" 00028 #include "OgreSDDataChunk.h" 00029 #include "OgreVector3.h" 00030 #include "OgreVector4.h" 00031 #include "OgreAutoParamDataSource.h" 00032 #include "OgreLight.h" 00033 #include "OgreControllerManager.h" 00034 #include "OgreRoot.h" 00035 #include "OgreRenderSystem.h" 00036 #include "OgreRenderSystemCapabilities.h" 00037 00038 namespace Ogre 00039 { 00040 //----------------------------------------------------------------------------- 00041 GpuProgram::GpuProgram(const String& name, GpuProgramType gptype, const String& syntaxCode) 00042 : mType(gptype), mLoadFromFile(true), mSyntaxCode(syntaxCode), mSkeletalAnimation(false), 00043 mPassSurfaceAndLightStates(false) 00044 { 00045 mName = name; 00046 } 00047 //----------------------------------------------------------------------------- 00048 void GpuProgram::setSourceFile(const String& filename) 00049 { 00050 mFilename = filename; 00051 mSource = ""; 00052 mLoadFromFile = true; 00053 } 00054 //----------------------------------------------------------------------------- 00055 void GpuProgram::setSource(const String& source) 00056 { 00057 mSource = source; 00058 mFilename = ""; 00059 mLoadFromFile = false; 00060 } 00061 00062 //----------------------------------------------------------------------------- 00063 void GpuProgram::load(void) 00064 { 00065 if (mIsLoaded) 00066 { 00067 unload(); 00068 } 00069 if (mLoadFromFile) 00070 { 00071 // find & load source code 00072 SDDataChunk chunk; 00073 GpuProgramManager::getSingleton()._findResourceData(mFilename, chunk); 00074 mSource = chunk.getAsString(); 00075 } 00076 00077 // Call polymorphic load 00078 loadFromSource(); 00079 00080 mIsLoaded = true; 00081 } 00082 //----------------------------------------------------------------------------- 00083 bool GpuProgram::isSupported(void) const 00084 { 00085 // If skeletal animation is being done, we need support for UBYTE4 00086 if (isSkeletalAnimationIncluded() && 00087 !Root::getSingleton().getRenderSystem()->getCapabilities() 00088 ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4)) 00089 { 00090 return false; 00091 } 00092 return GpuProgramManager::getSingleton().isSyntaxSupported(mSyntaxCode); 00093 } 00094 //----------------------------------------------------------------------------- 00095 GpuProgramParametersSharedPtr GpuProgram::createParameters(void) 00096 { 00097 // Default implementation simply returns standard parameters. 00098 GpuProgramParametersSharedPtr ret = 00099 GpuProgramManager::getSingleton().createParameters(); 00100 // Copy in default parameters if present 00101 if (!mDefaultParams.isNull()) 00102 ret->copyConstantsFrom(*(mDefaultParams.get())); 00103 00104 return ret; 00105 } 00106 //----------------------------------------------------------------------------- 00107 GpuProgramParametersSharedPtr GpuProgram::getDefaultParameters(void) 00108 { 00109 if (mDefaultParams.isNull()) 00110 { 00111 mDefaultParams = createParameters(); 00112 } 00113 return mDefaultParams; 00114 } 00115 //----------------------------------------------------------------------------- 00116 GpuProgramParameters::GpuProgramParameters() 00117 : mTransposeMatrices(false), mAutoAddParamName(false) 00118 { 00119 } 00120 //----------------------------------------------------------------------------- 00121 void GpuProgramParameters::setConstant(size_t index, const Vector4& vec) 00122 { 00123 setConstant(index, vec.val, 1); 00124 } 00125 //----------------------------------------------------------------------------- 00126 void GpuProgramParameters::setConstant(size_t index, const Vector3& vec) 00127 { 00128 setConstant(index, Vector4(vec.x, vec.y, vec.z, 1.0f)); 00129 } 00130 //----------------------------------------------------------------------------- 00131 void GpuProgramParameters::setConstant(size_t index, const Matrix4& m) 00132 { 00133 // set as 4x 4-element floats 00134 if (mTransposeMatrices) 00135 { 00136 Matrix4 t = m.transpose(); 00137 GpuProgramParameters::setConstant(index++, t[0], 1); 00138 GpuProgramParameters::setConstant(index++, t[1], 1); 00139 GpuProgramParameters::setConstant(index++, t[2], 1); 00140 GpuProgramParameters::setConstant(index, t[3], 1); 00141 } 00142 else 00143 { 00144 GpuProgramParameters::setConstant(index++, m[0], 1); 00145 GpuProgramParameters::setConstant(index++, m[1], 1); 00146 GpuProgramParameters::setConstant(index++, m[2], 1); 00147 GpuProgramParameters::setConstant(index, m[3], 1); 00148 } 00149 } 00150 //----------------------------------------------------------------------------- 00151 void GpuProgramParameters::setConstant(size_t index, const Matrix4* pMatrix, 00152 size_t numEntries) 00153 { 00154 for (size_t i = 0; i < numEntries; ++i) 00155 { 00156 const Matrix4& m = pMatrix[i]; 00157 00158 if (mTransposeMatrices) 00159 { 00160 Matrix4 t = m.transpose(); 00161 GpuProgramParameters::setConstant(index++, t[0], 1); 00162 GpuProgramParameters::setConstant(index++, t[1], 1); 00163 GpuProgramParameters::setConstant(index++, t[2], 1); 00164 GpuProgramParameters::setConstant(index++, t[3], 1); 00165 } 00166 else 00167 { 00168 GpuProgramParameters::setConstant(index++, m[0], 1); 00169 GpuProgramParameters::setConstant(index++, m[1], 1); 00170 GpuProgramParameters::setConstant(index++, m[2], 1); 00171 GpuProgramParameters::setConstant(index++, m[3], 1); 00172 } 00173 } 00174 } 00175 //----------------------------------------------------------------------------- 00176 void GpuProgramParameters::setConstant(size_t index, const ColourValue& colour) 00177 { 00178 setConstant(index, colour.val, 1); 00179 } 00180 //----------------------------------------------------------------------------- 00181 void GpuProgramParameters::setConstant(size_t index, const Real *val, size_t count) 00182 { 00183 // Expand if required 00184 if (mRealConstants.size() < index + count) 00185 mRealConstants.resize(index + count); 00186 00187 // Copy in chunks of 4 00188 while (count--) 00189 { 00190 RealConstantEntry* e = &(mRealConstants[index++]); 00191 e->isSet = true; 00192 memcpy(e->val, val, sizeof(Real) * 4); 00193 val += 4; 00194 } 00195 00196 } 00197 //----------------------------------------------------------------------------- 00198 void GpuProgramParameters::setConstant(size_t index, const int *val, size_t count) 00199 { 00200 // Expand if required 00201 if (mIntConstants.size() < index + count) 00202 mIntConstants.resize(index + count); 00203 00204 // Copy in chunks of 4 00205 while (count--) 00206 { 00207 IntConstantEntry* e = &(mIntConstants[index++]); 00208 e->isSet = true; 00209 memcpy(e->val, val, sizeof(int) * 4); 00210 val += 4; 00211 } 00212 } 00213 //----------------------------------------------------------------------------- 00214 void GpuProgramParameters::setAutoConstant(size_t index, AutoConstantType acType, size_t extraInfo) 00215 { 00216 mAutoConstants.push_back(AutoConstantEntry(acType, index, extraInfo)); 00217 } 00218 //----------------------------------------------------------------------------- 00219 void GpuProgramParameters::clearAutoConstants(void) 00220 { 00221 mAutoConstants.clear(); 00222 } 00223 //----------------------------------------------------------------------------- 00224 GpuProgramParameters::AutoConstantIterator GpuProgramParameters::getAutoConstantIterator(void) const 00225 { 00226 return AutoConstantIterator(mAutoConstants.begin(), mAutoConstants.end()); 00227 } 00228 //----------------------------------------------------------------------------- 00229 void GpuProgramParameters::_updateAutoParamsNoLights(const AutoParamDataSource& source) 00230 { 00231 if (!hasAutoConstants()) return; // abort early if no autos 00232 Vector3 vec3; 00233 Vector4 vec4; 00234 size_t index; 00235 size_t numMatrices; 00236 const Matrix4* pMatrix; 00237 size_t m; 00238 00239 AutoConstantList::const_iterator i, iend; 00240 iend = mAutoConstants.end(); 00241 for (i = mAutoConstants.begin(); i != iend; ++i) 00242 { 00243 switch(i->paramType) 00244 { 00245 case ACT_WORLD_MATRIX: 00246 setConstant(i->index, source.getWorldMatrix()); 00247 break; 00248 case ACT_WORLD_MATRIX_ARRAY: 00249 setConstant(i->index, source.getWorldMatrixArray(), 00250 source.getWorldMatrixCount()); 00251 break; 00252 case ACT_WORLD_MATRIX_ARRAY_3x4: 00253 // Loop over matrices 00254 pMatrix = source.getWorldMatrixArray(); 00255 numMatrices = source.getWorldMatrixCount(); 00256 index = i->index; 00257 for (m = 0; m < numMatrices; ++m) 00258 { 00259 GpuProgramParameters::setConstant(index++, (*pMatrix)[0], 1); 00260 GpuProgramParameters::setConstant(index++, (*pMatrix)[1], 1); 00261 GpuProgramParameters::setConstant(index++, (*pMatrix)[2], 1); 00262 ++pMatrix; 00263 } 00264 00265 break; 00266 case ACT_VIEW_MATRIX: 00267 setConstant(i->index, source.getViewMatrix()); 00268 break; 00269 case ACT_PROJECTION_MATRIX: 00270 setConstant(i->index, source.getProjectionMatrix()); 00271 break; 00272 case ACT_WORLDVIEW_MATRIX: 00273 setConstant(i->index, source.getWorldViewMatrix()); 00274 break; 00275 case ACT_VIEWPROJ_MATRIX: 00276 setConstant(i->index, source.getViewProjectionMatrix()); 00277 break; 00278 case ACT_WORLDVIEWPROJ_MATRIX: 00279 setConstant(i->index, source.getWorldViewProjMatrix()); 00280 break; 00281 case ACT_INVERSE_WORLD_MATRIX: 00282 setConstant(i->index, source.getInverseWorldMatrix()); 00283 break; 00284 case ACT_INVERSE_WORLDVIEW_MATRIX: 00285 setConstant(i->index, source.getInverseWorldViewMatrix()); 00286 break; 00287 case ACT_CAMERA_POSITION_OBJECT_SPACE: 00288 setConstant(i->index, source.getCameraPositionObjectSpace()); 00289 break; 00290 // NB ambient light still here because it's not related to a specific light 00291 case ACT_AMBIENT_LIGHT_COLOUR: 00292 setConstant(i->index, source.getAmbientLightColour()); 00293 break; 00294 case ACT_TEXTURE_VIEWPROJ_MATRIX: 00295 setConstant(i->index, source.getTextureViewProjMatrix()); 00296 break; 00297 case ACT_CUSTOM: 00298 source.getCurrentRenderable()->_updateCustomGpuParameter(*i, this); 00299 break; 00300 default: 00301 break; 00302 } 00303 } 00304 } 00305 //----------------------------------------------------------------------------- 00306 void GpuProgramParameters::_updateAutoParamsLightsOnly(const AutoParamDataSource& source) 00307 { 00308 if (!hasAutoConstants()) return; // abort early if no autos 00309 Vector3 vec3; 00310 Vector4 vec4; 00311 00312 AutoConstantList::const_iterator i, iend; 00313 iend = mAutoConstants.end(); 00314 for (i = mAutoConstants.begin(); i != iend; ++i) 00315 { 00316 switch(i->paramType) 00317 { 00318 case ACT_LIGHT_DIFFUSE_COLOUR: 00319 setConstant(i->index, source.getLight(i->data).getDiffuseColour()); 00320 break; 00321 case ACT_LIGHT_SPECULAR_COLOUR: 00322 setConstant(i->index, source.getLight(i->data).getSpecularColour()); 00323 break; 00324 case ACT_LIGHT_POSITION: 00325 // Get as 4D vector, works for directional lights too 00326 setConstant(i->index, 00327 source.getLight(i->data).getAs4DVector()); 00328 break; 00329 case ACT_LIGHT_DIRECTION: 00330 vec3 = source.getLight(i->data).getDerivedDirection(); 00331 // Set as 4D vector for compatibility 00332 setConstant(i->index, Vector4(vec3.x, vec3.y, vec3.z, 1.0f)); 00333 break; 00334 case ACT_LIGHT_POSITION_OBJECT_SPACE: 00335 setConstant(i->index, 00336 source.getInverseWorldMatrix() * source.getLight(i->data).getAs4DVector()); 00337 break; 00338 case ACT_LIGHT_DIRECTION_OBJECT_SPACE: 00339 vec3 = source.getInverseWorldMatrix() * 00340 source.getLight(i->data).getDerivedDirection(); 00341 vec3.normalise(); 00342 // Set as 4D vector for compatibility 00343 setConstant(i->index, Vector4(vec3.x, vec3.y, vec3.z, 1.0f)); 00344 break; 00345 case ACT_LIGHT_DISTANCE_OBJECT_SPACE: 00346 vec3 = source.getInverseWorldMatrix() * source.getLight(i->data).getDerivedPosition(); 00347 setConstant(i->index, vec3.length()); 00348 break; 00349 case ACT_SHADOW_EXTRUSION_DISTANCE: 00350 setConstant(i->index, source.getShadowExtrusionDistance()); 00351 break; 00352 case ACT_LIGHT_ATTENUATION: 00353 // range, const, linear, quad 00354 const Light& l = source.getLight(i->data); 00355 vec4.x = l.getAttenuationRange(); 00356 vec4.y = l.getAttenuationConstant(); 00357 vec4.z = l.getAttenuationLinear(); 00358 vec4.w = l.getAttenuationQuadric(); 00359 setConstant(i->index, vec4); 00360 break; 00361 } 00362 } 00363 } 00364 //--------------------------------------------------------------------------- 00365 void GpuProgramParameters::_mapParameterNameToIndex(const String& name, 00366 size_t index) 00367 { 00368 mParamNameMap[name] = index; 00369 } 00370 //--------------------------------------------------------------------------- 00371 size_t GpuProgramParameters::getParamIndex(const String& name) 00372 { 00373 ParamNameMap::const_iterator i = mParamNameMap.find(name); 00374 if (i == mParamNameMap.end()) 00375 { 00376 // name not found in map, should it be added to the map? 00377 if(mAutoAddParamName) 00378 { 00379 // determine index 00380 // don't know which Constants list the name is for 00381 // so pick the largest index 00382 size_t index = (mRealConstants.size() > mIntConstants.size()) ? 00383 mRealConstants.size() : mIntConstants.size(); 00384 // allow for at least one Vector4 00385 mRealConstants.resize(index + 1); 00386 mIntConstants.resize(index + 1); 00387 _mapParameterNameToIndex(name, index); 00388 return index; 00389 } 00390 else 00391 { 00392 Except(Exception::ERR_ITEM_NOT_FOUND, "Cannot find a parameter named " + name, 00393 "GpuProgramParameters::getParamIndex"); 00394 } 00395 } 00396 return i->second; 00397 } 00398 //--------------------------------------------------------------------------- 00399 void GpuProgramParameters::setNamedConstant(const String& name, Real val) 00400 { 00401 setConstant(getParamIndex(name), val); 00402 } 00403 //--------------------------------------------------------------------------- 00404 void GpuProgramParameters::setNamedConstant(const String& name, int val) 00405 { 00406 setConstant(getParamIndex(name), val); 00407 } 00408 //--------------------------------------------------------------------------- 00409 void GpuProgramParameters::setNamedConstant(const String& name, const Vector4& vec) 00410 { 00411 setConstant(getParamIndex(name), vec); 00412 } 00413 //--------------------------------------------------------------------------- 00414 void GpuProgramParameters::setNamedConstant(const String& name, const Vector3& vec) 00415 { 00416 setConstant(getParamIndex(name), vec); 00417 } 00418 //--------------------------------------------------------------------------- 00419 void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4& m) 00420 { 00421 setConstant(getParamIndex(name), m); 00422 } 00423 //--------------------------------------------------------------------------- 00424 void GpuProgramParameters::setNamedConstant(const String& name, const Matrix4* m, 00425 size_t numEntries) 00426 { 00427 setConstant(getParamIndex(name), m, numEntries); 00428 } 00429 //--------------------------------------------------------------------------- 00430 void GpuProgramParameters::setNamedConstant(const String& name, const Real *val, size_t count) 00431 { 00432 setConstant(getParamIndex(name), val, count); 00433 } 00434 //--------------------------------------------------------------------------- 00435 void GpuProgramParameters::setNamedConstant(const String& name, const ColourValue& colour) 00436 { 00437 setConstant(getParamIndex(name), colour); 00438 } 00439 //--------------------------------------------------------------------------- 00440 void GpuProgramParameters::setNamedConstant(const String& name, const int *val, size_t count) 00441 { 00442 setConstant(getParamIndex(name), val, count); 00443 } 00444 //--------------------------------------------------------------------------- 00445 void GpuProgramParameters::setNamedAutoConstant(const String& name, AutoConstantType acType, size_t extraInfo) 00446 { 00447 setAutoConstant(getParamIndex(name), acType, extraInfo); 00448 } 00449 //--------------------------------------------------------------------------- 00450 void GpuProgramParameters::setConstantFromTime(size_t index, Real factor) 00451 { 00452 // Create controller 00453 ControllerManager::getSingleton().createGpuProgramTimerParam(this, index, factor); 00454 00455 } 00456 //--------------------------------------------------------------------------- 00457 void GpuProgramParameters::setNamedConstantFromTime(const String& name, Real factor) 00458 { 00459 setConstantFromTime(getParamIndex(name), factor); 00460 } 00461 //--------------------------------------------------------------------------- 00462 GpuProgramParameters::RealConstantIterator GpuProgramParameters::getRealConstantIterator(void) const 00463 { 00464 return RealConstantIterator(mRealConstants.begin(), mRealConstants.end()); 00465 } 00466 //--------------------------------------------------------------------------- 00467 GpuProgramParameters::IntConstantIterator GpuProgramParameters::getIntConstantIterator(void) const 00468 { 00469 return IntConstantIterator(mIntConstants.begin(), mIntConstants.end()); 00470 } 00471 00472 //--------------------------------------------------------------------------- 00473 GpuProgramParameters::RealConstantEntry* GpuProgramParameters::getRealConstantEntry(const size_t index) 00474 { 00475 if (index < mRealConstants.size()) 00476 { 00477 return &(mRealConstants[index]); 00478 } 00479 else 00480 { 00481 return NULL; 00482 } 00483 } 00484 00485 //--------------------------------------------------------------------------- 00486 GpuProgramParameters::IntConstantEntry* GpuProgramParameters::getIntConstantEntry(const size_t index) 00487 { 00488 if (index < mIntConstants.size()) 00489 { 00490 return &(mIntConstants[index]); 00491 } 00492 else 00493 { 00494 return NULL; 00495 } 00496 } 00497 00498 //--------------------------------------------------------------------------- 00499 GpuProgramParameters::RealConstantEntry* GpuProgramParameters::getNamedRealConstantEntry(const String& name) 00500 { 00501 // check if name is found 00502 ParamNameMap::const_iterator i = mParamNameMap.find(name); 00503 00504 if (i == mParamNameMap.end()) 00505 { 00506 // no valid name found 00507 return NULL; 00508 } 00509 else 00510 { 00511 // name found: return the entry 00512 return getRealConstantEntry(i->second); 00513 } 00514 00515 } 00516 00517 //--------------------------------------------------------------------------- 00518 GpuProgramParameters::IntConstantEntry* GpuProgramParameters::getNamedIntConstantEntry(const String& name) 00519 { 00520 // check if name is found 00521 ParamNameMap::const_iterator i = mParamNameMap.find(name); 00522 00523 if (i == mParamNameMap.end()) 00524 { 00525 // no valid name found 00526 return NULL; 00527 } 00528 else 00529 { 00530 // name found: return the entry 00531 return getIntConstantEntry(i->second); 00532 } 00533 00534 } 00535 00536 //--------------------------------------------------------------------------- 00537 void GpuProgramParameters::copyConstantsFrom(const GpuProgramParameters& source) 00538 { 00539 // Iterate over fixed parameters 00540 RealConstantIterator ri = source.getRealConstantIterator(); 00541 ushort i = 0; 00542 while(ri.hasMoreElements()) 00543 { 00544 RealConstantEntry re = ri.getNext(); 00545 if (re.isSet) 00546 { 00547 setConstant(i, re.val, 4); 00548 } 00549 ++i; 00550 00551 } 00552 IntConstantIterator ii = source.getIntConstantIterator(); 00553 i = 0; 00554 while (ii.hasMoreElements()) 00555 { 00556 IntConstantEntry ie = ii.getNext(); 00557 if (ie.isSet) 00558 { 00559 setConstant(i, ie.val, 4); 00560 } 00561 ++i; 00562 } 00563 00564 // Iterate over auto parameters 00565 // Clear existing auto constants 00566 clearAutoConstants(); 00567 AutoConstantIterator ai = source.getAutoConstantIterator(); 00568 while (ai.hasMoreElements()) 00569 { 00570 AutoConstantEntry ae = ai.getNext(); 00571 setAutoConstant(ae.index, ae.paramType, ae.data); 00572 } 00573 00574 // need to copy Parameter names from the source 00575 mParamNameMap = source.mParamNameMap; 00576 00577 } 00578 00579 }
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:27 2004