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

Revision 692, 13.5 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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                // setup constant definition
226                // is it float or int
227                GpuProgramParameters::ElementType elementType = GpuProgramParameters::ET_INT;
228                // NOTE: all float enums are grouped together and occur before CG_INT which is the first of the int enums
229                // CG_FIXED1 is the last float type
230                if (paramType <= CG_FIXED1)
231                    elementType = GpuProgramParameters::ET_REAL;
232                params->addConstantDefinition(paramName, index, 0, elementType);
233            }
234            // Get next
235            parameter = cgGetNextLeafParameter(parameter);
236        }
237
238       
239    }
240    //-----------------------------------------------------------------------
241    CgProgram::CgProgram(ResourceManager* creator, const String& name,
242        ResourceHandle handle, const String& group, bool isManual,
243        ManualResourceLoader* loader, CGcontext context)
244        : HighLevelGpuProgram(creator, name, handle, group, isManual, loader),
245        mCgContext(context), mCgProgram(0),
246        mSelectedCgProfile(CG_PROFILE_UNKNOWN), mCgArguments(0)
247    {
248        if (createParamDictionary("CgProgram"))
249        {
250            setupBaseParamDictionary();
251
252            ParamDictionary* dict = getParamDictionary();
253
254            dict->addParameter(ParameterDef("entry_point",
255                "The entry point for the Cg program.",
256                PT_STRING),&msCmdEntryPoint);
257            dict->addParameter(ParameterDef("profiles",
258                "Space-separated list of Cg profiles supported by this profile.",
259                PT_STRING),&msCmdProfiles);
260            dict->addParameter(ParameterDef("compile_arguments",
261                "A string of compilation arguments to pass to the Cg compiler.",
262                PT_STRING),&msCmdArgs);
263        }
264       
265    }
266    //-----------------------------------------------------------------------
267    CgProgram::~CgProgram()
268    {
269        freeCgArgs();
270        // have to call this here reather than in Resource destructor
271        // since calling virtual methods in base destructors causes crash
272        if (mIsLoaded)
273        {
274            unload();
275        }
276        else
277        {
278            unloadHighLevel();
279        }
280    }
281    //-----------------------------------------------------------------------
282    bool CgProgram::isSupported(void) const
283    {
284                // If skeletal animation is being done, we need support for UBYTE4
285                if (isSkeletalAnimationIncluded() &&
286                        !Root::getSingleton().getRenderSystem()->getCapabilities()
287                                ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
288                {
289                        return false;
290                }
291
292                StringVector::const_iterator i, iend;
293        iend = mProfiles.end();
294        // Check to see if any of the profiles are supported
295        for (i = mProfiles.begin(); i != iend; ++i)
296        {
297            if (GpuProgramManager::getSingleton().isSyntaxSupported(*i))
298            {
299                return true;
300            }
301        }
302        return false;
303
304    }
305    //-----------------------------------------------------------------------
306    void CgProgram::setProfiles(const StringVector& profiles)
307    {
308        mProfiles.clear();
309        StringVector::const_iterator i, iend;
310        iend = profiles.end();
311        for (i = profiles.begin(); i != iend; ++i)
312        {
313            mProfiles.push_back(*i);
314        }
315    }
316
317    //-----------------------------------------------------------------------
318    const String& CgProgram::getLanguage(void) const
319    {
320        static const String language = "cg";
321
322        return language;
323    }
324
325
326    //-----------------------------------------------------------------------
327    //-----------------------------------------------------------------------
328    String CgProgram::CmdEntryPoint::doGet(const void *target) const
329    {
330        return static_cast<const CgProgram*>(target)->getEntryPoint();
331    }
332    void CgProgram::CmdEntryPoint::doSet(void *target, const String& val)
333    {
334        static_cast<CgProgram*>(target)->setEntryPoint(val);
335    }
336    //-----------------------------------------------------------------------
337    String CgProgram::CmdProfiles::doGet(const void *target) const
338    {
339        return StringConverter::toString(
340            static_cast<const CgProgram*>(target)->getProfiles() );
341    }
342    void CgProgram::CmdProfiles::doSet(void *target, const String& val)
343    {
344        static_cast<CgProgram*>(target)->setProfiles(StringUtil::split(val));
345    }
346    //-----------------------------------------------------------------------
347    String CgProgram::CmdArgs::doGet(const void *target) const
348    {
349        return static_cast<const CgProgram*>(target)->getCompileArguments();
350    }
351    void CgProgram::CmdArgs::doSet(void *target, const String& val)
352    {
353        static_cast<CgProgram*>(target)->setCompileArguments(val);
354    }
355
356}
Note: See TracBrowser for help on using the repository browser.