CmCgProgram.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2011 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "CmCgProgram.h"
  25. #include "CmGpuProgramManager.h"
  26. #include "CmHighLevelGpuProgramManager.h"
  27. #include "CmDebug.h"
  28. #include "CmException.h"
  29. namespace CamelotEngine {
  30. void checkForCgError(const String& ogreMethod, const String& errorTextPrefix, CGcontext context)
  31. {
  32. CGerror error = cgGetError();
  33. if (error != CG_NO_ERROR)
  34. {
  35. String msg = errorTextPrefix + cgGetErrorString(error);
  36. if (error == CG_COMPILER_ERROR)
  37. {
  38. // Get listing with full compile errors
  39. msg = msg + "\n" + cgGetLastListing(context);
  40. }
  41. CM_EXCEPT(InternalErrorException, msg);
  42. }
  43. }
  44. GpuProgramProfile cgProfileToGpuProgramProfile(const String& profile)
  45. {
  46. if(profile == "ps_1_1")
  47. return GPP_PS_1_1;
  48. else if(profile == "ps_1_2")
  49. return GPP_PS_1_2;
  50. else if(profile == "ps_1_3")
  51. return GPP_PS_1_3;
  52. else if(profile == "ps_1_4")
  53. return GPP_PS_1_4;
  54. else if(profile == "ps_2_0")
  55. return GPP_PS_2_0;
  56. else if(profile == "ps_2_a")
  57. return GPP_PS_2_a;
  58. else if(profile == "ps_2_b")
  59. return GPP_PS_2_b;
  60. else if(profile == "ps_3_0")
  61. return GPP_PS_3_0;
  62. else if(profile == "ps_4_0")
  63. return GPP_PS_4_0;
  64. else if(profile == "vs_1_1")
  65. return GPP_VS_1_1;
  66. else if(profile == "vs_2_0")
  67. return GPP_VS_2_0;
  68. else if(profile == "vs_2_a")
  69. return GPP_VS_2_a;
  70. else if(profile == "vs_3_0")
  71. return GPP_VS_3_0;
  72. else if(profile == "vs_4_0")
  73. return GPP_VS_4_0;
  74. else
  75. assert(false); // Unsupported profile
  76. return GPP_NONE;
  77. }
  78. String gpuProgramProfileToCgProfile(GpuProgramProfile profile)
  79. {
  80. switch(profile)
  81. {
  82. case GPP_PS_1_1:
  83. return "ps_1_1";
  84. case GPP_PS_1_2:
  85. return "ps_1_2";
  86. case GPP_PS_1_3:
  87. return "ps_1_3";
  88. case GPP_PS_1_4:
  89. return "ps_1_4";
  90. case GPP_PS_2_0:
  91. return "ps_2_0";
  92. case GPP_PS_2_a:
  93. return "ps_2_a";
  94. case GPP_PS_2_b:
  95. return "ps_2_b";
  96. case GPP_PS_3_0:
  97. return "ps_3_0";
  98. case GPP_PS_4_0:
  99. return "ps_4_0";
  100. case GPP_VS_1_1:
  101. return "vs_1_1";
  102. case GPP_VS_2_0:
  103. return "vs_2_0";
  104. case GPP_VS_2_a:
  105. return "vs_2_a";
  106. case GPP_VS_3_0:
  107. return "vs_3_0";
  108. case GPP_VS_4_0:
  109. return "vs_4_0";
  110. default:
  111. assert(false); // Unsupported profile
  112. }
  113. return "";
  114. }
  115. //-----------------------------------------------------------------------
  116. void CgProgram::selectProfile(void)
  117. {
  118. mSelectedProfile.clear();
  119. mSelectedCgProfile = CG_PROFILE_UNKNOWN;
  120. mSelectedProfile = gpuProgramProfileToCgProfile(mProfile);
  121. GpuProgramManager& gpuMgr = GpuProgramManager::instance();
  122. //if (gpuMgr.isSyntaxSupported(mSelectedProfile))
  123. {
  124. mSelectedCgProfile = cgGetProfile(mSelectedProfile.c_str());
  125. // Check for errors
  126. checkForCgError("CgProgram::selectProfile",
  127. "Unable to find CG profile enum for program.", mCgContext);
  128. }
  129. //else
  130. // mSelectedProfile.clear();
  131. }
  132. //-----------------------------------------------------------------------
  133. void CgProgram::buildArgs(void)
  134. {
  135. vector<String>::type args;
  136. if (!mCompileArgs.empty())
  137. args = StringUtil::split(mCompileArgs);
  138. vector<String>::type::const_iterator i;
  139. if (mSelectedCgProfile == CG_PROFILE_VS_1_1)
  140. {
  141. // Need the 'dcls' argument whenever we use this profile
  142. // otherwise compilation of the assembler will fail
  143. bool dclsFound = false;
  144. for (i = args.begin(); i != args.end(); ++i)
  145. {
  146. if (*i == "dcls")
  147. {
  148. dclsFound = true;
  149. break;
  150. }
  151. }
  152. if (!dclsFound)
  153. {
  154. args.push_back("-profileopts");
  155. args.push_back("dcls");
  156. }
  157. }
  158. // Now split args into that god-awful char** that Cg insists on
  159. freeCgArgs();
  160. mCgArguments = (char**)malloc(sizeof(char*) * (args.size() + 1));
  161. int index = 0;
  162. for (i = args.begin(); i != args.end(); ++i, ++index)
  163. {
  164. mCgArguments[index] = (char*)malloc(sizeof(char) * (i->length() + 1));
  165. strcpy(mCgArguments[index], i->c_str());
  166. }
  167. // Null terminate list
  168. mCgArguments[index] = 0;
  169. }
  170. //-----------------------------------------------------------------------
  171. void CgProgram::freeCgArgs(void)
  172. {
  173. if (mCgArguments)
  174. {
  175. size_t index = 0;
  176. char* current = mCgArguments[index];
  177. while (current)
  178. {
  179. free(current);
  180. mCgArguments[index] = 0;
  181. current = mCgArguments[++index];
  182. }
  183. free(mCgArguments);
  184. mCgArguments = 0;
  185. }
  186. }
  187. //-----------------------------------------------------------------------
  188. void CgProgram::loadFromSource(void)
  189. {
  190. // Create Cg Program
  191. selectProfile();
  192. if (mSelectedCgProfile == CG_PROFILE_UNKNOWN)
  193. {
  194. gDebug().log("Attempted to load Cg program but no supported "
  195. "profile was found.", "RenderSystem");
  196. return;
  197. }
  198. buildArgs();
  199. // TODO PORT - This doesn't load includes
  200. // deal with includes
  201. String sourceToUse = mSource;
  202. //String sourceToUse = resolveCgIncludes(mSource, this, mFilename);
  203. mCgProgram = cgCreateProgram(mCgContext, CG_SOURCE, sourceToUse.c_str(),
  204. mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments));
  205. // Test
  206. //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM));
  207. // Check for errors
  208. checkForCgError("CgProgram::loadFromSource",
  209. "Unable to compile Cg program", mCgContext);
  210. }
  211. //-----------------------------------------------------------------------
  212. void CgProgram::createLowLevelImpl(void)
  213. {
  214. // ignore any previous error
  215. if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError)
  216. {
  217. if (mSelectedCgProfile == CG_PROFILE_VS_4_0 || mSelectedCgProfile == CG_PROFILE_PS_4_0)
  218. {
  219. String hlslSourceFromCg = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);
  220. // Create a high-level program, give it the same name as us
  221. HighLevelGpuProgramPtr vp =
  222. HighLevelGpuProgramManager::instance().createProgram(
  223. hlslSourceFromCg, "main", "hlsl", mType, cgProfileToGpuProgramProfile(mSelectedProfile));
  224. vp->load();
  225. mAssemblerProgram = vp;
  226. }
  227. else
  228. {
  229. String shaderAssemblerCode = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);
  230. // Create a low-level program, give it the same name as us
  231. mAssemblerProgram =
  232. GpuProgramManager::instance().createProgram(
  233. shaderAssemblerCode,
  234. mType,
  235. mSelectedProfile);
  236. }
  237. // Shader params need to be forwarded to low level implementation
  238. mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired());
  239. }
  240. }
  241. //-----------------------------------------------------------------------
  242. void CgProgram::unloadHighLevelImpl(void)
  243. {
  244. // Unload Cg Program
  245. // Lowlevel program will get unloaded elsewhere
  246. if (mCgProgram)
  247. {
  248. cgDestroyProgram(mCgProgram);
  249. checkForCgError("CgProgram::unloadImpl",
  250. "Error while unloading Cg program",
  251. mCgContext);
  252. mCgProgram = 0;
  253. }
  254. }
  255. //-----------------------------------------------------------------------
  256. void CgProgram::buildConstantDefinitions() const
  257. {
  258. // Derive parameter names from Cg
  259. createParameterMappingStructures(true);
  260. if (!mCgProgram)
  261. return;
  262. recurseParams(cgGetFirstParameter(mCgProgram, CG_PROGRAM));
  263. recurseParams(cgGetFirstParameter(mCgProgram, CG_GLOBAL));
  264. }
  265. //---------------------------------------------------------------------
  266. void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize) const
  267. {
  268. while (parameter != 0)
  269. {
  270. // Look for uniform (non-sampler) parameters only
  271. // Don't bother enumerating unused parameters, especially since they will
  272. // be optimised out and therefore not in the indexed versions
  273. CGtype paramType = cgGetParameterType(parameter);
  274. if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
  275. paramType != CG_SAMPLER1D &&
  276. paramType != CG_SAMPLER2D &&
  277. paramType != CG_SAMPLER3D &&
  278. paramType != CG_SAMPLERCUBE &&
  279. paramType != CG_SAMPLERRECT &&
  280. cgGetParameterDirection(parameter) != CG_OUT &&
  281. cgIsParameterReferenced(parameter))
  282. {
  283. int arraySize;
  284. switch(paramType)
  285. {
  286. case CG_STRUCT:
  287. recurseParams(cgGetFirstStructParameter(parameter));
  288. break;
  289. case CG_ARRAY:
  290. // Support only 1-dimensional arrays
  291. arraySize = cgGetArraySize(parameter, 0);
  292. recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize);
  293. break;
  294. default:
  295. // Normal path (leaf)
  296. String paramName = cgGetParameterName(parameter);
  297. size_t logicalIndex = cgGetParameterResourceIndex(parameter);
  298. // Get the parameter resource, to calculate the physical index
  299. CGresource res = cgGetParameterResource(parameter);
  300. bool isRegisterCombiner = false;
  301. size_t regCombinerPhysicalIndex = 0;
  302. switch (res)
  303. {
  304. case CG_COMBINER_STAGE_CONST0:
  305. // register combiner, const 0
  306. // the index relates to the texture stage; store this as (stage * 2) + 0
  307. regCombinerPhysicalIndex = logicalIndex * 2;
  308. isRegisterCombiner = true;
  309. break;
  310. case CG_COMBINER_STAGE_CONST1:
  311. // register combiner, const 1
  312. // the index relates to the texture stage; store this as (stage * 2) + 1
  313. regCombinerPhysicalIndex = (logicalIndex * 2) + 1;
  314. isRegisterCombiner = true;
  315. break;
  316. default:
  317. // normal constant
  318. break;
  319. }
  320. // Trim the '[0]' suffix if it exists, we will add our own indexing later
  321. if (StringUtil::endsWith(paramName, "[0]", false))
  322. {
  323. paramName.erase(paramName.size() - 3);
  324. }
  325. GpuConstantDefinition def;
  326. def.arraySize = contextArraySize;
  327. mapTypeAndElementSize(paramType, isRegisterCombiner, def);
  328. if (def.constType == GCT_UNKNOWN)
  329. {
  330. gDebug().log("Problem parsing the following Cg Uniform: '" + paramName + "'", "RenderSystem");
  331. // next uniform
  332. parameter = cgGetNextParameter(parameter);
  333. continue;
  334. }
  335. if (isRegisterCombiner)
  336. {
  337. def.physicalIndex = regCombinerPhysicalIndex;
  338. }
  339. else
  340. {
  341. // base position on existing buffer contents
  342. if (def.isFloat())
  343. {
  344. def.physicalIndex = mFloatLogicalToPhysical->bufferSize;
  345. }
  346. else
  347. {
  348. def.physicalIndex = mIntLogicalToPhysical->bufferSize;
  349. }
  350. }
  351. def.logicalIndex = logicalIndex;
  352. mConstantDefs->map.insert(GpuConstantDefinitionMap::value_type(paramName, def));
  353. // Record logical / physical mapping
  354. if (def.isFloat())
  355. {
  356. CM_LOCK_MUTEX(mFloatLogicalToPhysical->mutex)
  357. mFloatLogicalToPhysical->map.insert(
  358. GpuLogicalIndexUseMap::value_type(logicalIndex,
  359. GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
  360. mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
  361. mConstantDefs->floatBufferSize = mFloatLogicalToPhysical->bufferSize;
  362. }
  363. else
  364. {
  365. CM_LOCK_MUTEX(mIntLogicalToPhysical->mutex)
  366. mIntLogicalToPhysical->map.insert(
  367. GpuLogicalIndexUseMap::value_type(logicalIndex,
  368. GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
  369. mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
  370. mConstantDefs->intBufferSize = mIntLogicalToPhysical->bufferSize;
  371. }
  372. // Deal with array indexing
  373. mConstantDefs->generateConstantDefinitionArrayEntries(paramName, def);
  374. break;
  375. }
  376. }
  377. // Get next
  378. parameter = cgGetNextParameter(parameter);
  379. }
  380. }
  381. //-----------------------------------------------------------------------
  382. void CgProgram::mapTypeAndElementSize(CGtype cgType, bool isRegisterCombiner,
  383. GpuConstantDefinition& def) const
  384. {
  385. if (isRegisterCombiner)
  386. {
  387. // register combiners are the only single-float entries in our buffer
  388. def.constType = GCT_FLOAT1;
  389. def.elementSize = 1;
  390. }
  391. else
  392. {
  393. switch(cgType)
  394. {
  395. case CG_FLOAT:
  396. case CG_FLOAT1:
  397. case CG_HALF:
  398. case CG_HALF1:
  399. def.constType = GCT_FLOAT1;
  400. break;
  401. case CG_FLOAT2:
  402. case CG_HALF2:
  403. def.constType = GCT_FLOAT2;
  404. break;
  405. case CG_FLOAT3:
  406. case CG_HALF3:
  407. def.constType = GCT_FLOAT3;
  408. break;
  409. case CG_FLOAT4:
  410. case CG_HALF4:
  411. def.constType = GCT_FLOAT4;
  412. break;
  413. case CG_FLOAT2x2:
  414. case CG_HALF2x2:
  415. def.constType = GCT_MATRIX_2X2;
  416. break;
  417. case CG_FLOAT2x3:
  418. case CG_HALF2x3:
  419. def.constType = GCT_MATRIX_2X3;
  420. break;
  421. case CG_FLOAT2x4:
  422. case CG_HALF2x4:
  423. def.constType = GCT_MATRIX_2X4;
  424. break;
  425. case CG_FLOAT3x2:
  426. case CG_HALF3x2:
  427. def.constType = GCT_MATRIX_3X2;
  428. break;
  429. case CG_FLOAT3x3:
  430. case CG_HALF3x3:
  431. def.constType = GCT_MATRIX_3X3;
  432. break;
  433. case CG_FLOAT3x4:
  434. case CG_HALF3x4:
  435. def.constType = GCT_MATRIX_3X4;
  436. break;
  437. case CG_FLOAT4x2:
  438. case CG_HALF4x2:
  439. def.constType = GCT_MATRIX_4X2;
  440. break;
  441. case CG_FLOAT4x3:
  442. case CG_HALF4x3:
  443. def.constType = GCT_MATRIX_4X3;
  444. break;
  445. case CG_FLOAT4x4:
  446. case CG_HALF4x4:
  447. def.constType = GCT_MATRIX_4X4;
  448. break;
  449. case CG_INT:
  450. case CG_INT1:
  451. def.constType = GCT_INT1;
  452. break;
  453. case CG_INT2:
  454. def.constType = GCT_INT2;
  455. break;
  456. case CG_INT3:
  457. def.constType = GCT_INT3;
  458. break;
  459. case CG_INT4:
  460. def.constType = GCT_INT4;
  461. break;
  462. default:
  463. def.constType = GCT_UNKNOWN;
  464. break;
  465. }
  466. // Cg pads
  467. def.elementSize = GpuConstantDefinition::getElementSize(def.constType, true);
  468. }
  469. }
  470. //-----------------------------------------------------------------------
  471. CgProgram::CgProgram(CGcontext context)
  472. : HighLevelGpuProgram(),
  473. mCgContext(context), mCgProgram(0),
  474. mSelectedCgProfile(CG_PROFILE_UNKNOWN), mCgArguments(0)
  475. {
  476. }
  477. //-----------------------------------------------------------------------
  478. CgProgram::~CgProgram()
  479. {
  480. freeCgArgs();
  481. unloadHighLevel();
  482. }
  483. //-----------------------------------------------------------------------
  484. bool CgProgram::isSupported(void) const
  485. {
  486. if (mCompileError || !isRequiredCapabilitiesSupported())
  487. return false;
  488. //String selectedProfile = gpuProgramProfileToCgProfile(mProfile);
  489. //if (GpuProgramManager::instance().isSyntaxSupported(selectedProfile))
  490. return true;
  491. return false;
  492. }
  493. //-----------------------------------------------------------------------
  494. void CgProgram::setProfiles(const vector<String>::type& profiles)
  495. {
  496. mProfiles.clear();
  497. vector<String>::type::const_iterator i, iend;
  498. iend = profiles.end();
  499. for (i = profiles.begin(); i != iend; ++i)
  500. {
  501. mProfiles.push_back(*i);
  502. }
  503. }
  504. //-----------------------------------------------------------------------
  505. String CgProgram::resolveCgIncludes(const String& inSource, Resource* resourceBeingLoaded, const String& fileName)
  506. {
  507. String outSource;
  508. // TODO PORT - Includes are not handled ATM
  509. // output will be at least this big
  510. //outSource.reserve(inSource.length());
  511. //size_t startMarker = 0;
  512. //size_t i = inSource.find("#include");
  513. //while (i != String::npos)
  514. //{
  515. // size_t includePos = i;
  516. // size_t afterIncludePos = includePos + 8;
  517. // size_t newLineBefore = inSource.rfind("\n", includePos);
  518. // // check we're not in a comment
  519. // size_t lineCommentIt = inSource.rfind("//", includePos);
  520. // if (lineCommentIt != String::npos)
  521. // {
  522. // if (newLineBefore == String::npos || lineCommentIt > newLineBefore)
  523. // {
  524. // // commented
  525. // i = inSource.find("#include", afterIncludePos);
  526. // continue;
  527. // }
  528. // }
  529. // size_t blockCommentIt = inSource.rfind("/*", includePos);
  530. // if (blockCommentIt != String::npos)
  531. // {
  532. // size_t closeCommentIt = inSource.rfind("*/", includePos);
  533. // if (closeCommentIt == String::npos || closeCommentIt < blockCommentIt)
  534. // {
  535. // // commented
  536. // i = inSource.find("#include", afterIncludePos);
  537. // continue;
  538. // }
  539. // }
  540. // // find following newline (or EOF)
  541. // size_t newLineAfter = inSource.find("\n", afterIncludePos);
  542. // // find include file string container
  543. // String endDelimeter = "\"";
  544. // size_t startIt = inSource.find("\"", afterIncludePos);
  545. // if (startIt == String::npos || startIt > newLineAfter)
  546. // {
  547. // // try <>
  548. // startIt = inSource.find("<", afterIncludePos);
  549. // if (startIt == String::npos || startIt > newLineAfter)
  550. // {
  551. // CM_EXCEPT(InternalErrorException,
  552. // "Badly formed #include directive (expected \" or <) in file "
  553. // + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos));
  554. // }
  555. // else
  556. // {
  557. // endDelimeter = ">";
  558. // }
  559. // }
  560. // size_t endIt = inSource.find(endDelimeter, startIt+1);
  561. // if (endIt == String::npos || endIt <= startIt)
  562. // {
  563. // CM_EXCEPT(InternalErrorException,
  564. // "Badly formed #include directive (expected " + endDelimeter + ") in file "
  565. // + fileName + ": " + inSource.substr(includePos, newLineAfter-includePos));
  566. // }
  567. // // extract filename
  568. // String filename(inSource.substr(startIt+1, endIt-startIt-1));
  569. // // open included file
  570. // DataStreamPtr resource = ResourceGroupManager::getSingleton().
  571. // openResource(filename, resourceBeingLoaded->getGroup(), true, resourceBeingLoaded);
  572. // // replace entire include directive line
  573. // // copy up to just before include
  574. // if (newLineBefore != String::npos && newLineBefore >= startMarker)
  575. // outSource.append(inSource.substr(startMarker, newLineBefore-startMarker+1));
  576. // size_t lineCount = 0;
  577. // size_t lineCountPos = 0;
  578. //
  579. // // Count the line number of #include statement
  580. // lineCountPos = outSource.find('\n');
  581. // while(lineCountPos != String::npos)
  582. // {
  583. // lineCountPos = outSource.find('\n', lineCountPos+1);
  584. // lineCount++;
  585. // }
  586. // // Add #line to the start of the included file to correct the line count
  587. // outSource.append("#line 1 \"" + filename + "\"\n");
  588. // outSource.append(resource->getAsString());
  589. // // Add #line to the end of the included file to correct the line count
  590. // outSource.append("\n#line " + toString(lineCount) +
  591. // "\"" + fileName + "\"\n");
  592. // startMarker = newLineAfter;
  593. // if (startMarker != String::npos)
  594. // i = inSource.find("#include", startMarker);
  595. // else
  596. // i = String::npos;
  597. //}
  598. //// copy any remaining characters
  599. //outSource.append(inSource.substr(startMarker));
  600. return outSource;
  601. }
  602. //-----------------------------------------------------------------------
  603. const String& CgProgram::getLanguage(void) const
  604. {
  605. static const String language = "cg";
  606. return language;
  607. }
  608. }