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

# OgreCgProgram.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://www.ogre3d.org/
    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 "OgreCgProgram.h"
    00026 #include "OgreGpuProgramManager.h"
    00027 #include "OgreStringConverter.h"
    00028 #include "OgreRoot.h"
    00029 #include "OgreRenderSystem.h"
    00030 #include "OgreRenderSystemCapabilities.h"
    00031
    00032 namespace Ogre {
    00033     //-----------------------------------------------------------------------
    00034     CgProgram::CmdEntryPoint CgProgram::msCmdEntryPoint;
    00035     CgProgram::CmdProfiles CgProgram::msCmdProfiles;
    00036     CgProgram::CmdArgs CgProgram::msCmdArgs;
    00037     //-----------------------------------------------------------------------
    00038     void CgProgram::selectProfile(void)
    00039     {
    00040         mSelectedProfile = "";
    00041         mSelectedCgProfile = CG_PROFILE_UNKNOWN;
    00042
    00043         StringVector::iterator i, iend;
    00044         iend = mProfiles.end();
    00045         GpuProgramManager& gpuMgr = GpuProgramManager::getSingleton();
    00046         for (i = mProfiles.begin(); i != iend; ++i)
    00047         {
    00048             if (gpuMgr.isSyntaxSupported(*i))
    00049             {
    00050                 mSelectedProfile = *i;
    00051                 mSelectedCgProfile = cgGetProfile(mSelectedProfile.c_str());
    00052                 // Check for errors
    00053                 checkForCgError("CgProgram::selectProfile",
    00054                     "Unable to find CG profile enum for program " + mName + ": ", mCgContext);
    00055                 break;
    00056             }
    00057         }
    00058     }
    00059     //-----------------------------------------------------------------------
    00060     void CgProgram::buildArgs(void)
    00061     {
    00062         StringVector args;
    00063         if (!mCompileArgs.empty())
    00064             args = StringUtil::split(mCompileArgs);
    00065
    00066         StringVector::const_iterator i;
    00067         if (mSelectedCgProfile == CG_PROFILE_VS_1_1)
    00068         {
    00069             // Need the 'dcls' argument whenever we use this profile
    00070             // otherwise compilation of the assembler will fail
    00071             bool dclsFound = false;
    00072             for (i = args.begin(); i != args.end(); ++i)
    00073             {
    00074                 if (*i == "dcls")
    00075                 {
    00076                     dclsFound = true;
    00077                     break;
    00078                 }
    00079             }
    00080             if (!dclsFound)
    00081             {
    00082                 args.push_back("-profileopts dcls");
    00083             }
    00084         }
    00085         // Now split args into that god-awful char** that Cg insists on
    00086         freeCgArgs();
    00087         mCgArguments = new char*[args.size() + 1];
    00088         int index = 0;
    00089         for (i = args.begin(); i != args.end(); ++i, ++index)
    00090         {
    00091             mCgArguments[index] = new char[i->length() + 1];
    00092             strcpy(mCgArguments[index], i->c_str());
    00093         }
    00094         // Null terminate list
    00095         mCgArguments[index] = 0;
    00096
    00097
    00098     }
    00099     //-----------------------------------------------------------------------
    00100     void CgProgram::freeCgArgs(void)
    00101     {
    00102         if (mCgArguments)
    00103         {
    00104             size_t index = 0;
    00105             char* current = mCgArguments[index];
    00106             while (current)
    00107             {
    00108                 delete [] current;
    00109                 current = mCgArguments[++index];
    00110             }
    00111             delete [] mCgArguments;
    00112             mCgArguments = 0;
    00113         }
    00114     }
    00115     //-----------------------------------------------------------------------
    00116     void CgProgram::loadFromSource(void)
    00117     {
    00118         // Create Cg Program
    00119         selectProfile();
    00120         buildArgs();
    00121         mCgProgram = cgCreateProgram(mCgContext, CG_SOURCE, mSource.c_str(),
    00122             mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments));
    00123
    00124         // Test
    00125         //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM));
    00126
    00127         // Check for errors
    00128         checkForCgError("CgProgram::loadFromSource",
    00129             "Unable to compile Cg program " + mName + ": ", mCgContext);
    00130
    00131     }
    00132     //-----------------------------------------------------------------------
    00133     void CgProgram::createLowLevelImpl(void)
    00134     {
    00135         // Create a low-level program, give it the same name as us
    00136         mAssemblerProgram =
    00137             GpuProgramManager::getSingleton().createProgramFromString(
    00138                 mName,
    00139                 cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM),
    00140                 mType,
    00141                 mSelectedProfile);
    00142
    00143     }
    00144     //-----------------------------------------------------------------------
    00145     void CgProgram::unloadImpl(void)
    00146     {
    00147         // Unload Cg Program
    00148         // Lowlevel program will get unloaded elsewhere
    00149         if (mCgProgram)
    00150         {
    00151             cgDestroyProgram(mCgProgram);
    00152             checkForCgError("CgProgram::unloadImpl",
    00153                 "Error while unloading Cg program " + mName + ": ",
    00154                 mCgContext);
    00155             mCgProgram = 0;
    00156         }
    00157     }
    00158     //-----------------------------------------------------------------------
    00159     void CgProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
    00160     {
    00161         // Derive parameter names from Cg
    00162         assert(mCgProgram && "Cg program not loaded!");
    00163         // Note use of 'leaf' format so we only get bottom-level params, not structs
    00164         CGparameter parameter = cgGetFirstLeafParameter(mCgProgram, CG_PROGRAM);
    00165         while (parameter != 0)
    00166         {
    00167             // Look for uniform (non-sampler) parameters only
    00168             // Don't bother enumerating unused parameters, especially since they will
    00169             // be optimised out and therefore not in the indexed versions
    00170             CGtype paramType = cgGetParameterType(parameter);
    00171
    00172             // *** test
    00173             //String tempName = cgGetParameterName(parameter);
    00174             //size_t tempindex = cgGetParameterResourceIndex(parameter);
    00175             //LogManager::getSingleton().logMessage(
    00176             //    tempName + " -> " + StringConverter::toString(tempindex));
    00177
    00178             // *** end test
    00179
    00180             if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
    00181                 paramType != CG_SAMPLER1D &&
    00182                 paramType != CG_SAMPLER2D &&
    00183                 paramType != CG_SAMPLER3D &&
    00184                 paramType != CG_SAMPLERCUBE &&
    00185                 paramType != CG_SAMPLERRECT &&
    00186                 cgGetParameterDirection(parameter) != CG_OUT &&
    00187                 cgIsParameterReferenced(parameter))
    00188             {
    00189                 String paramName = cgGetParameterName(parameter);
    00190                 size_t index = cgGetParameterResourceIndex(parameter);
    00191
    00192                 // Get the parameter resource, so we know what type we're dealing with
    00193                 CGresource res = cgGetParameterResource(parameter);
    00194                 switch (res)
    00195                 {
    00196                 case CG_COMBINER_STAGE_CONST0:
    00197                     // register combiner, const 0
    00198                     // the index relates to the texture stage; store this as (stage * 2) + 0
    00199                     index = index * 2;
    00200                     break;
    00201                 case CG_COMBINER_STAGE_CONST1:
    00202                     // register combiner, const 1
    00203                     // the index relates to the texture stage; store this as (stage * 2) + 1
    00204                     index = (index * 2) + 1;
    00205                     break;
    00206                 default:
    00207                     // do nothing, normal constant
    00208                     break;
    00209                 };
    00210                 params->_mapParameterNameToIndex(paramName, index);
    00211             }
    00212             // Get next
    00213             parameter = cgGetNextLeafParameter(parameter);
    00214         }
    00215
    00216
    00217     }
    00218     //-----------------------------------------------------------------------
    00219     CgProgram::CgProgram(const String& name, GpuProgramType gpType,
    00220         const String& language, CGcontext context)
    00221         : HighLevelGpuProgram(name, gpType, language), mCgContext(context),
    00222         mCgProgram(0), mSelectedCgProfile(CG_PROFILE_UNKNOWN), mCgArguments(0)
    00223     {
    00224         if (createParamDictionary("CgProgram"))
    00225         {
    00226             ParamDictionary* dict = getParamDictionary();
    00227
    00228             dict->addParameter(ParameterDef("entry_point",
    00229                 "The entry point for the Cg program.",
    00230                 PT_STRING),&msCmdEntryPoint);
    00231             dict->addParameter(ParameterDef("profiles",
    00232                 "Space-separated list of Cg profiles supported by this profile.",
    00233                 PT_STRING),&msCmdProfiles);
    00234             dict->addParameter(ParameterDef("compile_arguments",
    00235                 "A string of compilation arguments to pass to the Cg compiler.",
    00236                 PT_STRING),&msCmdArgs);
    00237         }
    00238
    00239     }
    00240     //-----------------------------------------------------------------------
    00241     CgProgram::~CgProgram()
    00242     {
    00243         freeCgArgs();
    00244         // unload will be called by superclass
    00245     }
    00246     //-----------------------------------------------------------------------
    00247     bool CgProgram::isSupported(void) const
    00248     {
    00249         // If skeletal animation is being done, we need support for UBYTE4
    00250         if (isSkeletalAnimationIncluded() &&
    00251             !Root::getSingleton().getRenderSystem()->getCapabilities()
    00252                 ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
    00253         {
    00254             return false;
    00255         }
    00256
    00257         StringVector::const_iterator i, iend;
    00258         iend = mProfiles.end();
    00259         // Check to see if any of the profiles are supported
    00260         for (i = mProfiles.begin(); i != iend; ++i)
    00261         {
    00262             if (GpuProgramManager::getSingleton().isSyntaxSupported(*i))
    00263             {
    00264                 return true;
    00265             }
    00266         }
    00267         return false;
    00268
    00269     }
    00270     //-----------------------------------------------------------------------
    00271     void CgProgram::setProfiles(const StringVector& profiles)
    00272     {
    00273         mProfiles.clear();
    00274         StringVector::const_iterator i, iend;
    00275         iend = profiles.end();
    00276         for (i = profiles.begin(); i != iend; ++i)
    00277         {
    00278             mProfiles.push_back(*i);
    00279         }
    00280     }
    00281     //-----------------------------------------------------------------------
    00282     //-----------------------------------------------------------------------
    00283     String CgProgram::CmdEntryPoint::doGet(const void *target) const
    00284     {
    00285         return static_cast<const CgProgram*>(target)->getEntryPoint();
    00286     }
    00287     void CgProgram::CmdEntryPoint::doSet(void *target, const String& val)
    00288     {
    00289         static_cast<CgProgram*>(target)->setEntryPoint(val);
    00290     }
    00291     //-----------------------------------------------------------------------
    00292     String CgProgram::CmdProfiles::doGet(const void *target) const
    00293     {
    00294         return StringConverter::toString(
    00295             static_cast<const CgProgram*>(target)->getProfiles() );
    00296     }
    00297     void CgProgram::CmdProfiles::doSet(void *target, const String& val)
    00298     {
    00299         static_cast<CgProgram*>(target)->setProfiles(StringUtil::split(val));
    00300     }
    00301     //-----------------------------------------------------------------------
    00302     String CgProgram::CmdArgs::doGet(const void *target) const
    00303     {
    00304         return static_cast<const CgProgram*>(target)->getCompileArguments();
    00305     }
    00306     void CgProgram::CmdArgs::doSet(void *target, const String& val)
    00307     {
    00308         static_cast<CgProgram*>(target)->setCompileArguments(val);
    00309     }
    00310
    00311 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:17 2004