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

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:20 2004