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

OgreD3D9HLSLProgram.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 "OgreD3D9HLSLProgram.h"
00026 #include "OgreGpuProgramManager.h"
00027 #include "OgreStringConverter.h"
00028 #include "OgreD3D9GpuProgram.h"
00029 #include "OgreGpuProgram.h"
00030 
00031 namespace Ogre {
00032     //-----------------------------------------------------------------------
00033     D3D9HLSLProgram::CmdEntryPoint D3D9HLSLProgram::msCmdEntryPoint;
00034     D3D9HLSLProgram::CmdTarget D3D9HLSLProgram::msCmdTarget;
00035     //-----------------------------------------------------------------------
00036     //-----------------------------------------------------------------------
00037     void D3D9HLSLProgram::loadFromSource(void)
00038     {
00039         LPD3DXBUFFER errors = 0;
00040 
00041         // Compile & assemble into microcode
00042         HRESULT hr = D3DXCompileShader(
00043             mSource.c_str(),
00044             static_cast<UINT>(mSource.length()),
00045             NULL, //no preprocessor defines
00046             NULL, //no includes
00047             mEntryPoint.c_str(),
00048             mTarget.c_str(),
00049             NULL, // no compile flags
00050             &mpMicroCode,
00051             &errors,
00052             &mpConstTable);
00053 
00054         if (FAILED(hr))
00055         {
00056             Except(hr, "Cannot assemble D3D9 high-level shader " + mName + 
00057                 static_cast<const char*>(errors->GetBufferPointer()),
00058                 "D3D9HLSLProgram::loadFromSource");
00059         }
00060 
00061 
00062     }
00063     //-----------------------------------------------------------------------
00064     void D3D9HLSLProgram::createLowLevelImpl(void)
00065     {
00066         // Create a low-level program, give it the same name as us
00067         mAssemblerProgram = 
00068             GpuProgramManager::getSingleton().createProgramFromString(
00069                 mName, 
00070                 "",// dummy source, since we'll be using microcode
00071                 mType, 
00072                 mTarget);
00073         static_cast<D3D9GpuProgram*>(mAssemblerProgram)->setExternalMicrocode(mpMicroCode);
00074 
00075     }
00076     //-----------------------------------------------------------------------
00077     void D3D9HLSLProgram::unloadImpl(void)
00078     {
00079         SAFE_RELEASE(mpMicroCode);
00080         // mpConstTable is embedded inside the shader, so will get released with it
00081         mpConstTable = NULL;
00082 
00083     }
00084     //-----------------------------------------------------------------------
00085     void D3D9HLSLProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
00086     {
00087         // Derive parameter names from const table
00088         assert(mpConstTable && "Program not loaded!");
00089         // Get contents of the constant table
00090         D3DXCONSTANTTABLE_DESC desc;
00091         HRESULT hr = mpConstTable->GetDesc(&desc);
00092 
00093         if (FAILED(hr))
00094         {
00095             Except(Exception::ERR_INTERNAL_ERROR, 
00096                 "Cannot retrieve constant descriptions from HLSL program.", 
00097                 "D3D9HLSLProgram::populateParameterNames");
00098         }
00099         // Iterate over the constants
00100         for (unsigned int i = 0; i < desc.Constants; ++i)
00101         {
00102             // Recursively descend through the structure levels
00103             // Since D3D9 has no nice 'leaf' method like Cg (sigh)
00104             processParamElement(NULL, "", i, params);
00105         }
00106 
00107         
00108     }
00109     //-----------------------------------------------------------------------
00110     void D3D9HLSLProgram::processParamElement(D3DXHANDLE parent, String prefix, 
00111         unsigned int index, GpuProgramParametersSharedPtr params)
00112     {
00113         D3DXHANDLE hConstant = mpConstTable->GetConstant(parent, index);
00114 
00115         // Since D3D HLSL doesn't deal with naming of array and struct parameters
00116         // automatically, we have to do it by hand
00117 
00118         D3DXCONSTANT_DESC desc;
00119         unsigned int numParams = 1;
00120         HRESULT hr = mpConstTable->GetConstantDesc(hConstant, &desc, &numParams);
00121         if (FAILED(hr))
00122         {
00123             Except(Exception::ERR_INTERNAL_ERROR, 
00124                 "Cannot retrieve constant description from HLSL program.", 
00125                 "D3D9HLSLProgram::processParamElement");
00126         }
00127 
00128         String paramName = desc.Name;
00129         // trim the odd '$' which appears at the start of the names in HLSL
00130         if (paramName.at(0) == '$')
00131             paramName.erase(paramName.begin());
00132 
00133         // If it's an array, elements will be > 1
00134         for (unsigned int e = 0; e < desc.Elements; ++e)
00135         {
00136             if (desc.Class == D3DXPC_STRUCT)
00137             {
00138                 // work out a new prefix for nested members, if it's an array, we need an index
00139                 if (desc.Elements > 1)
00140                     prefix = prefix + paramName + "[" + StringConverter::toString(e) + "].";
00141                 else
00142                     prefix = prefix + paramName + ".";
00143                 // Cascade into struct
00144                 for (unsigned int i = 0; i < desc.StructMembers; ++i)
00145                 {
00146                     processParamElement(hConstant, prefix, i, params);
00147                 }
00148             }
00149             else
00150             {
00151                 // Process params
00152                 if (desc.Type == D3DXPT_FLOAT || desc.Type == D3DXPT_INT || desc.Type == D3DXPT_BOOL)
00153                 {
00154                     size_t paramIndex = desc.RegisterIndex;
00155                     String name = prefix + paramName;
00156                     // If this is an array, need to append element index
00157                     if (desc.Elements > 1)
00158                         name += "[" + StringConverter::toString(e) + "]";
00159 
00160                     params->_mapParameterNameToIndex(name, paramIndex);
00161                 }
00162             }
00163         }
00164             
00165     }
00166     //-----------------------------------------------------------------------
00167     D3D9HLSLProgram::D3D9HLSLProgram(const String& name, GpuProgramType gpType, 
00168         const String& language)
00169         : HighLevelGpuProgram(name, gpType, language), mpMicroCode(NULL), 
00170         mpConstTable(NULL)
00171     {
00172         if (createParamDictionary("D3D9HLSLProgram"))
00173         {
00174             ParamDictionary* dict = getParamDictionary();
00175 
00176             dict->addParameter(ParameterDef("entry_point", 
00177                 "The entry point for the HLSL program.",
00178                 PT_STRING),&msCmdEntryPoint);
00179             dict->addParameter(ParameterDef("target", 
00180                 "Name of the assembler target to compile down to.",
00181                 PT_STRING),&msCmdTarget);
00182         }
00183         
00184     }
00185     //-----------------------------------------------------------------------
00186     D3D9HLSLProgram::~D3D9HLSLProgram()
00187     {
00188         // unload will be called by superclass
00189     }
00190     //-----------------------------------------------------------------------
00191     bool D3D9HLSLProgram::isSupported(void) const
00192     {
00193         return GpuProgramManager::getSingleton().isSyntaxSupported(mTarget);
00194     }
00195     //-----------------------------------------------------------------------
00196     GpuProgramParametersSharedPtr D3D9HLSLProgram::createParameters(void)
00197     {
00198         // Call superclass
00199         GpuProgramParametersSharedPtr params = HighLevelGpuProgram::createParameters();
00200 
00201         // D3D HLSL uses column-major matrices
00202         params->setTransposeMatrices(true);
00203 
00204         return params;
00205     }
00206     //-----------------------------------------------------------------------
00207     void D3D9HLSLProgram::setTarget(const String& target)
00208     {
00209         mTarget = target;
00210     }
00211     //-----------------------------------------------------------------------
00212     //-----------------------------------------------------------------------
00213     String D3D9HLSLProgram::CmdEntryPoint::doGet(const void *target) const
00214     {
00215         return static_cast<const D3D9HLSLProgram*>(target)->getEntryPoint();
00216     }
00217     void D3D9HLSLProgram::CmdEntryPoint::doSet(void *target, const String& val)
00218     {
00219         static_cast<D3D9HLSLProgram*>(target)->setEntryPoint(val);
00220     }
00221     //-----------------------------------------------------------------------
00222     String D3D9HLSLProgram::CmdTarget::doGet(const void *target) const
00223     {
00224         return static_cast<const D3D9HLSLProgram*>(target)->getTarget();
00225     }
00226     void D3D9HLSLProgram::CmdTarget::doSet(void *target, const String& val)
00227     {
00228         static_cast<D3D9HLSLProgram*>(target)->setTarget(val);
00229     }
00230 
00231 }

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:07 2004