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