source: OGRE/trunk/ogrenew/PlugIns/CgProgramManager/src/OgreCgProgram.cpp @ 690

Revision 690, 12.7 KB checked in by mattausch, 18 years ago (diff)

added ogre 1.07 main

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreCgProgram.h"
26#include "OgreGpuProgramManager.h"
27#include "OgreStringConverter.h"
28#include "OgreRoot.h"
29#include "OgreRenderSystem.h"
30#include "OgreRenderSystemCapabilities.h"
31#include "OgreLogManager.h"
32
33namespace Ogre {
34    //-----------------------------------------------------------------------
35    CgProgram::CmdEntryPoint CgProgram::msCmdEntryPoint;
36    CgProgram::CmdProfiles CgProgram::msCmdProfiles;
37    CgProgram::CmdArgs CgProgram::msCmdArgs;
38    //-----------------------------------------------------------------------
39    void CgProgram::selectProfile(void)
40    {
41        mSelectedProfile = "";
42        mSelectedCgProfile = CG_PROFILE_UNKNOWN;
43
44        StringVector::iterator i, iend;
45        iend = mProfiles.end();
46        GpuProgramManager& gpuMgr = GpuProgramManager::getSingleton();
47        for (i = mProfiles.begin(); i != iend; ++i)
48        {
49            if (gpuMgr.isSyntaxSupported(*i))
50            {
51                mSelectedProfile = *i;
52                mSelectedCgProfile = cgGetProfile(mSelectedProfile.c_str());
53                // Check for errors
54                checkForCgError("CgProgram::selectProfile",
55                    "Unable to find CG profile enum for program " + mName + ": ", mCgContext);
56                break;
57            }
58        }
59    }
60    //-----------------------------------------------------------------------
61    void CgProgram::buildArgs(void)
62    {
63        StringVector args;
64        if (!mCompileArgs.empty())
65            args = StringUtil::split(mCompileArgs);
66
67        StringVector::const_iterator i;
68        if (mSelectedCgProfile == CG_PROFILE_VS_1_1)
69        {
70            // Need the 'dcls' argument whenever we use this profile
71            // otherwise compilation of the assembler will fail
72            bool dclsFound = false;
73            for (i = args.begin(); i != args.end(); ++i)
74            {
75                if (*i == "dcls")
76                {
77                    dclsFound = true;
78                    break;
79                }
80            }
81            if (!dclsFound)
82            {
83                args.push_back("-profileopts");
84                                args.push_back("dcls");
85            }
86        }
87        // Now split args into that god-awful char** that Cg insists on
88        freeCgArgs();
89        mCgArguments = new char*[args.size() + 1];
90        int index = 0;
91        for (i = args.begin(); i != args.end(); ++i, ++index)
92        {
93            mCgArguments[index] = new char[i->length() + 1];
94            strcpy(mCgArguments[index], i->c_str());
95        }
96        // Null terminate list
97        mCgArguments[index] = 0;
98
99
100    }
101    //-----------------------------------------------------------------------
102    void CgProgram::freeCgArgs(void)
103    {
104        if (mCgArguments)
105        {
106            size_t index = 0;
107            char* current = mCgArguments[index];
108            while (current)
109            {
110                delete [] current;
111                current = mCgArguments[++index];
112            }
113            delete [] mCgArguments;
114            mCgArguments = 0;
115        }
116    }
117    //-----------------------------------------------------------------------
118    void CgProgram::loadFromSource(void)
119    {
120        // Create Cg Program
121        selectProfile();
122                if (mSelectedCgProfile == CG_PROFILE_UNKNOWN)
123                {
124                        LogManager::getSingleton().logMessage(
125                                "Attempted to load Cg program '" + mName + "', but no suported "
126                                "profile was found. ");
127                        return;
128                }
129        buildArgs();
130        mCgProgram = cgCreateProgram(mCgContext, CG_SOURCE, mSource.c_str(),
131            mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments));
132
133        // Test
134        //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM));
135
136        // Check for errors
137        checkForCgError("CgProgram::loadFromSource",
138            "Unable to compile Cg program " + mName + ": ", mCgContext);
139
140    }
141    //-----------------------------------------------------------------------
142    void CgProgram::createLowLevelImpl(void)
143    {
144                // ignore any previous error
145                if (mSelectedCgProfile != CG_PROFILE_UNKNOWN)
146                {
147
148                        // Create a low-level program, give it the same name as us
149                        mAssemblerProgram =
150                                GpuProgramManager::getSingleton().createProgramFromString(
151                                        mName,
152                                        mGroup,
153                                        cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM),
154                                        mType,
155                                        mSelectedProfile);
156                }
157    }
158    //-----------------------------------------------------------------------
159    void CgProgram::unloadHighLevelImpl(void)
160    {
161        // Unload Cg Program
162        // Lowlevel program will get unloaded elsewhere
163        if (mCgProgram)
164        {
165            cgDestroyProgram(mCgProgram);
166            checkForCgError("CgProgram::unloadImpl",
167                "Error while unloading Cg program " + mName + ": ",
168                mCgContext);
169            mCgProgram = 0;
170        }
171    }
172    //-----------------------------------------------------------------------
173    void CgProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
174    {
175        // Derive parameter names from Cg
176        assert(mCgProgram && "Cg program not loaded!");
177        // Note use of 'leaf' format so we only get bottom-level params, not structs
178        CGparameter parameter = cgGetFirstLeafParameter(mCgProgram, CG_PROGRAM);
179        while (parameter != 0)
180        {
181            // Look for uniform (non-sampler) parameters only
182            // Don't bother enumerating unused parameters, especially since they will
183            // be optimised out and therefore not in the indexed versions
184            CGtype paramType = cgGetParameterType(parameter);
185           
186            // *** test
187            //String tempName = cgGetParameterName(parameter);
188            //size_t tempindex = cgGetParameterResourceIndex(parameter);
189            //LogManager::getSingleton().logMessage(
190            //    tempName + " -> " + StringConverter::toString(tempindex));
191
192            // *** end test
193
194            if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
195                paramType != CG_SAMPLER1D &&
196                paramType != CG_SAMPLER2D &&
197                paramType != CG_SAMPLER3D &&
198                paramType != CG_SAMPLERCUBE &&
199                paramType != CG_SAMPLERRECT &&
200                cgGetParameterDirection(parameter) != CG_OUT &&
201                cgIsParameterReferenced(parameter))
202            {
203                String paramName = cgGetParameterName(parameter);
204                size_t index = cgGetParameterResourceIndex(parameter);
205
206                // Get the parameter resource, so we know what type we're dealing with
207                CGresource res = cgGetParameterResource(parameter);
208                switch (res)
209                {
210                case CG_COMBINER_STAGE_CONST0:
211                    // register combiner, const 0
212                    // the index relates to the texture stage; store this as (stage * 2) + 0
213                    index = index * 2;
214                    break;
215                case CG_COMBINER_STAGE_CONST1:
216                    // register combiner, const 1
217                    // the index relates to the texture stage; store this as (stage * 2) + 1
218                    index = (index * 2) + 1;
219                    break;
220                default:
221                    // do nothing, normal constant
222                    break;
223                };
224                params->_mapParameterNameToIndex(paramName, index);
225            }
226            // Get next
227            parameter = cgGetNextLeafParameter(parameter);
228        }
229
230       
231    }
232    //-----------------------------------------------------------------------
233    CgProgram::CgProgram(ResourceManager* creator, const String& name,
234        ResourceHandle handle, const String& group, bool isManual,
235        ManualResourceLoader* loader, CGcontext context)
236        : HighLevelGpuProgram(creator, name, handle, group, isManual, loader),
237        mCgContext(context), mCgProgram(0),
238        mSelectedCgProfile(CG_PROFILE_UNKNOWN), mCgArguments(0)
239    {
240        if (createParamDictionary("CgProgram"))
241        {
242            setupBaseParamDictionary();
243
244            ParamDictionary* dict = getParamDictionary();
245
246            dict->addParameter(ParameterDef("entry_point",
247                "The entry point for the Cg program.",
248                PT_STRING),&msCmdEntryPoint);
249            dict->addParameter(ParameterDef("profiles",
250                "Space-separated list of Cg profiles supported by this profile.",
251                PT_STRING),&msCmdProfiles);
252            dict->addParameter(ParameterDef("compile_arguments",
253                "A string of compilation arguments to pass to the Cg compiler.",
254                PT_STRING),&msCmdArgs);
255        }
256       
257    }
258    //-----------------------------------------------------------------------
259    CgProgram::~CgProgram()
260    {
261        freeCgArgs();
262        // have to call this here reather than in Resource destructor
263        // since calling virtual methods in base destructors causes crash
264        if (mIsLoaded)
265        {
266            unload();
267        }
268        else
269        {
270            unloadHighLevel();
271        }
272    }
273    //-----------------------------------------------------------------------
274    bool CgProgram::isSupported(void) const
275    {
276                // If skeletal animation is being done, we need support for UBYTE4
277                if (isSkeletalAnimationIncluded() &&
278                        !Root::getSingleton().getRenderSystem()->getCapabilities()
279                                ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
280                {
281                        return false;
282                }
283
284                StringVector::const_iterator i, iend;
285        iend = mProfiles.end();
286        // Check to see if any of the profiles are supported
287        for (i = mProfiles.begin(); i != iend; ++i)
288        {
289            if (GpuProgramManager::getSingleton().isSyntaxSupported(*i))
290            {
291                return true;
292            }
293        }
294        return false;
295
296    }
297    //-----------------------------------------------------------------------
298    void CgProgram::setProfiles(const StringVector& profiles)
299    {
300        mProfiles.clear();
301        StringVector::const_iterator i, iend;
302        iend = profiles.end();
303        for (i = profiles.begin(); i != iend; ++i)
304        {
305            mProfiles.push_back(*i);
306        }
307    }
308    //-----------------------------------------------------------------------
309    //-----------------------------------------------------------------------
310    String CgProgram::CmdEntryPoint::doGet(const void *target) const
311    {
312        return static_cast<const CgProgram*>(target)->getEntryPoint();
313    }
314    void CgProgram::CmdEntryPoint::doSet(void *target, const String& val)
315    {
316        static_cast<CgProgram*>(target)->setEntryPoint(val);
317    }
318    //-----------------------------------------------------------------------
319    String CgProgram::CmdProfiles::doGet(const void *target) const
320    {
321        return StringConverter::toString(
322            static_cast<const CgProgram*>(target)->getProfiles() );
323    }
324    void CgProgram::CmdProfiles::doSet(void *target, const String& val)
325    {
326        static_cast<CgProgram*>(target)->setProfiles(StringUtil::split(val));
327    }
328    //-----------------------------------------------------------------------
329    String CgProgram::CmdArgs::doGet(const void *target) const
330    {
331        return static_cast<const CgProgram*>(target)->getCompileArguments();
332    }
333    void CgProgram::CmdArgs::doSet(void *target, const String& val)
334    {
335        static_cast<CgProgram*>(target)->setCompileArguments(val);
336    }
337
338}
Note: See TracBrowser for help on using the repository browser.