Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGpuProgram.cpp

Go to the documentation of this file.
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