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