source: OGRE/trunk/ogrenew/RenderSystems/Direct3D9/src/OgreD3D9HLSLProgram.cpp @ 657

Revision 657, 9.9 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

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 "OgreD3D9HLSLProgram.h"
26#include "OgreGpuProgramManager.h"
27#include "OgreStringConverter.h"
28#include "OgreD3D9GpuProgram.h"
29#include "OgreGpuProgram.h"
30#include "OgreRoot.h"
31#include "OgreRenderSystem.h"
32#include "OgreRenderSystemCapabilities.h"
33
34namespace Ogre {
35    //-----------------------------------------------------------------------
36    D3D9HLSLProgram::CmdEntryPoint D3D9HLSLProgram::msCmdEntryPoint;
37    D3D9HLSLProgram::CmdTarget D3D9HLSLProgram::msCmdTarget;
38    //-----------------------------------------------------------------------
39    //-----------------------------------------------------------------------
40    void D3D9HLSLProgram::loadFromSource(void)
41    {
42        LPD3DXBUFFER errors = 0;
43
44        // Compile & assemble into microcode
45        HRESULT hr = D3DXCompileShader(
46            mSource.c_str(),
47            static_cast<UINT>(mSource.length()),
48            NULL, //no preprocessor defines
49            NULL, //no includes
50            mEntryPoint.c_str(),
51            mTarget.c_str(),
52            NULL, // no compile flags
53            &mpMicroCode,
54            &errors,
55            &mpConstTable);
56
57        if (FAILED(hr))
58        {
59            String message = "Cannot assemble D3D9 high-level shader " + mName + " Errors:\n" +
60                static_cast<const char*>(errors->GetBufferPointer());
61            errors->Release();
62            OGRE_EXCEPT(hr, message,
63                "D3D9HLSLProgram::loadFromSource");
64        }
65
66
67    }
68    //-----------------------------------------------------------------------
69    void D3D9HLSLProgram::createLowLevelImpl(void)
70    {
71        // Create a low-level program, give it the same name as us
72        mAssemblerProgram =
73            GpuProgramManager::getSingleton().createProgramFromString(
74                mName,
75                mGroup,
76                "",// dummy source, since we'll be using microcode
77                mType,
78                mTarget);
79        static_cast<D3D9GpuProgram*>(mAssemblerProgram.get())->setExternalMicrocode(mpMicroCode);
80
81    }
82    //-----------------------------------------------------------------------
83    void D3D9HLSLProgram::unloadHighLevelImpl(void)
84    {
85        SAFE_RELEASE(mpMicroCode);
86        SAFE_RELEASE(mpConstTable);
87
88    }
89    //-----------------------------------------------------------------------
90    void D3D9HLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
91    {
92        // Derive parameter names from const table
93        assert(mpConstTable && "Program not loaded!");
94        // Get contents of the constant table
95        D3DXCONSTANTTABLE_DESC desc;
96        HRESULT hr = mpConstTable->GetDesc(&desc);
97
98        if (FAILED(hr))
99        {
100            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
101                "Cannot retrieve constant descriptions from HLSL program.",
102                "D3D9HLSLProgram::populateParameterNames");
103        }
104        // Iterate over the constants
105        for (unsigned int i = 0; i < desc.Constants; ++i)
106        {
107            // Recursively descend through the structure levels
108            // Since D3D9 has no nice 'leaf' method like Cg (sigh)
109            processParamElement(NULL, "", i, params);
110        }
111
112       
113    }
114    //-----------------------------------------------------------------------
115    void D3D9HLSLProgram::processParamElement(D3DXHANDLE parent, String prefix,
116        unsigned int index, GpuProgramParametersSharedPtr params)
117    {
118        D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
119
120        // Since D3D HLSL doesn't deal with naming of array and struct parameters
121        // automatically, we have to do it by hand
122
123        D3DXCONSTANT_DESC desc;
124        unsigned int numParams = 1;
125        HRESULT hr = mpConstTable->GetConstantDesc(hConstant, &desc, &numParams);
126        if (FAILED(hr))
127        {
128            OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
129                "Cannot retrieve constant description from HLSL program.",
130                "D3D9HLSLProgram::processParamElement");
131        }
132
133        String paramName = desc.Name;
134        // trim the odd '$' which appears at the start of the names in HLSL
135        if (paramName.at(0) == '$')
136            paramName.erase(paramName.begin());
137
138        // If it's an array, elements will be > 1
139        for (unsigned int e = 0; e < desc.Elements; ++e)
140        {
141            if (desc.Class == D3DXPC_STRUCT)
142            {
143                // work out a new prefix for nested members, if it's an array, we need an index
144                if (desc.Elements > 1)
145                    prefix = prefix + paramName + "[" + StringConverter::toString(e) + "].";
146                else
147                    prefix = prefix + paramName + ".";
148                // Cascade into struct
149                for (unsigned int i = 0; i < desc.StructMembers; ++i)
150                {
151                    processParamElement(hConstant, prefix, i, params);
152                }
153            }
154            else
155            {
156                // Process params
157                if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
158                {
159                    size_t paramIndex = desc.RegisterIndex;
160                    String name = prefix + paramName;
161                    // If this is an array, need to append element index
162                    if (desc.Elements > 1)
163                        name += "[" + StringConverter::toString(e) + "]";
164
165                    params->_mapParameterNameToIndex(name, paramIndex);
166                }
167            }
168        }
169           
170    }
171    //-----------------------------------------------------------------------
172    D3D9HLSLProgram::D3D9HLSLProgram(ResourceManager* creator, const String& name,
173        ResourceHandle handle, const String& group, bool isManual,
174        ManualResourceLoader* loader)
175        : HighLevelGpuProgram(creator, name, handle, group, isManual, loader)
176        , mpMicroCode(NULL), mpConstTable(NULL)
177    {
178        if (createParamDictionary("D3D9HLSLProgram"))
179        {
180            setupBaseParamDictionary();
181            ParamDictionary* dict = getParamDictionary();
182
183            dict->addParameter(ParameterDef("entry_point",
184                "The entry point for the HLSL program.",
185                PT_STRING),&msCmdEntryPoint);
186            dict->addParameter(ParameterDef("target",
187                "Name of the assembler target to compile down to.",
188                PT_STRING),&msCmdTarget);
189        }
190       
191    }
192    //-----------------------------------------------------------------------
193    D3D9HLSLProgram::~D3D9HLSLProgram()
194    {
195        // have to call this here reather than in Resource destructor
196        // since calling virtual methods in base destructors causes crash
197        if (mIsLoaded)
198        {
199            unload();
200        }
201        else
202        {
203            unloadHighLevel();
204        }
205    }
206    //-----------------------------------------------------------------------
207    bool D3D9HLSLProgram::isSupported(void) const
208    {
209                // If skeletal animation is being done, we need support for UBYTE4
210                if (isSkeletalAnimationIncluded() &&
211                        !Root::getSingleton().getRenderSystem()->getCapabilities()
212                                ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
213                {
214                        return false;
215                }
216
217        return GpuProgramManager::getSingleton().isSyntaxSupported(mTarget);
218    }
219    //-----------------------------------------------------------------------
220    GpuProgramParametersSharedPtr D3D9HLSLProgram::createParameters(void)
221    {
222        // Call superclass
223        GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters();
224
225        // D3D HLSL uses column-major matrices
226        params->setTransposeMatrices(true);
227
228        return params;
229    }
230    //-----------------------------------------------------------------------
231    void D3D9HLSLProgram::setTarget(const String& target)
232    {
233        mTarget = target;
234    }
235    //-----------------------------------------------------------------------
236    //-----------------------------------------------------------------------
237    String D3D9HLSLProgram::CmdEntryPoint::doGet(const void *target) const
238    {
239        return static_cast<const D3D9HLSLProgram*>(target)->getEntryPoint();
240    }
241    void D3D9HLSLProgram::CmdEntryPoint::doSet(void *target, const String& val)
242    {
243        static_cast<D3D9HLSLProgram*>(target)->setEntryPoint(val);
244    }
245    //-----------------------------------------------------------------------
246    String D3D9HLSLProgram::CmdTarget::doGet(const void *target) const
247    {
248        return static_cast<const D3D9HLSLProgram*>(target)->getTarget();
249    }
250    void D3D9HLSLProgram::CmdTarget::doSet(void *target, const String& val)
251    {
252        static_cast<D3D9HLSLProgram*>(target)->setTarget(val);
253    }
254
255}
Note: See TracBrowser for help on using the repository browser.