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

Revision 692, 10.6 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 "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                    // setup constant definition
167                    // is it float or int
168                    GpuProgramParameters::ElementType elementType = GpuProgramParameters::ET_INT;
169                    if (desc.Type == D3DXPT_FLOAT)
170                        elementType = GpuProgramParameters::ET_REAL;
171                    params->addConstantDefinition(name, paramIndex, 0, elementType);
172                }
173            }
174        }
175           
176    }
177    //-----------------------------------------------------------------------
178    D3D9HLSLProgram::D3D9HLSLProgram(ResourceManager* creator, const String& name,
179        ResourceHandle handle, const String& group, bool isManual,
180        ManualResourceLoader* loader)
181        : HighLevelGpuProgram(creator, name, handle, group, isManual, loader)
182        , mpMicroCode(NULL), mpConstTable(NULL)
183    {
184        if (createParamDictionary("D3D9HLSLProgram"))
185        {
186            setupBaseParamDictionary();
187            ParamDictionary* dict = getParamDictionary();
188
189            dict->addParameter(ParameterDef("entry_point",
190                "The entry point for the HLSL program.",
191                PT_STRING),&msCmdEntryPoint);
192            dict->addParameter(ParameterDef("target",
193                "Name of the assembler target to compile down to.",
194                PT_STRING),&msCmdTarget);
195        }
196       
197    }
198    //-----------------------------------------------------------------------
199    D3D9HLSLProgram::~D3D9HLSLProgram()
200    {
201        // have to call this here reather than in Resource destructor
202        // since calling virtual methods in base destructors causes crash
203        if (mIsLoaded)
204        {
205            unload();
206        }
207        else
208        {
209            unloadHighLevel();
210        }
211    }
212    //-----------------------------------------------------------------------
213    bool D3D9HLSLProgram::isSupported(void) const
214    {
215                // If skeletal animation is being done, we need support for UBYTE4
216                if (isSkeletalAnimationIncluded() &&
217                        !Root::getSingleton().getRenderSystem()->getCapabilities()
218                                ->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
219                {
220                        return false;
221                }
222
223        return GpuProgramManager::getSingleton().isSyntaxSupported(mTarget);
224    }
225    //-----------------------------------------------------------------------
226    GpuProgramParametersSharedPtr D3D9HLSLProgram::createParameters(void)
227    {
228        // Call superclass
229        GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters();
230
231        // D3D HLSL uses column-major matrices
232        params->setTransposeMatrices(true);
233
234        return params;
235    }
236    //-----------------------------------------------------------------------
237    void D3D9HLSLProgram::setTarget(const String& target)
238    {
239        mTarget = target;
240    }
241
242    //-----------------------------------------------------------------------
243    const String& D3D9HLSLProgram::getLanguage(void) const
244    {
245        static const String language = "hlsl";
246
247        return language;
248    }
249
250    //-----------------------------------------------------------------------
251    //-----------------------------------------------------------------------
252    String D3D9HLSLProgram::CmdEntryPoint::doGet(const void *target) const
253    {
254        return static_cast<const D3D9HLSLProgram*>(target)->getEntryPoint();
255    }
256    void D3D9HLSLProgram::CmdEntryPoint::doSet(void *target, const String& val)
257    {
258        static_cast<D3D9HLSLProgram*>(target)->setEntryPoint(val);
259    }
260    //-----------------------------------------------------------------------
261    String D3D9HLSLProgram::CmdTarget::doGet(const void *target) const
262    {
263        return static_cast<const D3D9HLSLProgram*>(target)->getTarget();
264    }
265    void D3D9HLSLProgram::CmdTarget::doSet(void *target, const String& val)
266    {
267        static_cast<D3D9HLSLProgram*>(target)->setTarget(val);
268    }
269
270}
Note: See TracBrowser for help on using the repository browser.