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