ps1.0_program.cpp 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. #include "ps1.0_program.h"
  2. #include "nvparse_errors.h"
  3. #include "nvparse_externs.h"
  4. #include <string>
  5. #include <map>
  6. #include <algorithm>
  7. #include <string.h>
  8. #include <set>
  9. using namespace std;
  10. using namespace ps10;
  11. struct ltstr
  12. {
  13. bool operator()(const char* s1, const char* s2) const
  14. {
  15. return strcmp(s1, s2) < 0;
  16. }
  17. };
  18. #define DBG_MESG(msg, line) errors.set(msg, line)
  19. //#define DBG_MESG(msg, line)
  20. namespace ps10
  21. {
  22. std::map<int, std::pair<int,int> > constToStageAndConstMap;
  23. std::vector<int> constToStageArray;
  24. std::map<int, int> stageToConstMap; // to keep track of which constants have been used up for this stage.
  25. // r-value of 0 means none, r-value of 1 means c0 used, and r-value of 2 means both used.
  26. //std::map<int, int> constToStageMap;
  27. std::map<int, GLenum> stageToTargetMap;
  28. std::set<const char*, ltstr> alphaBlueRegisters; // Keeps track of whether the result of a register
  29. // was a dp3, if a register is in this set, it means that if it is used a source for the alpha
  30. // component the blue component should be used, and not the alpha component.
  31. void SetFinalCombinerStage();
  32. }
  33. void RemoveFromAlphaBlue(std::string s)
  34. {
  35. std::set<const char*, ltstr>::iterator iter =
  36. ps10::alphaBlueRegisters.find(s.c_str());
  37. if (iter != alphaBlueRegisters.end())
  38. alphaBlueRegisters.erase(iter);
  39. }
  40. /*
  41. void AddToMap(string s, int stage)
  42. {
  43. const char* cstr = s.c_str();
  44. if (cstr[0] == 'c')
  45. {
  46. int constNum = atoi(&cstr[1]);
  47. if (constNum < 0 || constNum > 7)
  48. return;
  49. constToStageMap[constNum] = stage;
  50. }
  51. }
  52. */
  53. bool AddToMap(string s, int stage, GLenum& constVal)
  54. {
  55. const char* cstr = s.c_str();
  56. if (cstr[0] == 'c')
  57. {
  58. int constNum = atoi(&cstr[1]);
  59. std::map<int, int>::iterator iter = stageToConstMap.find(stage);
  60. if (iter == stageToConstMap.end())
  61. {
  62. // no constants used for this stage.
  63. std::pair<int, int> temp;
  64. temp.first = stage;
  65. temp.second = 0;
  66. constToStageAndConstMap[constNum] = temp;
  67. stageToConstMap[stage] = 0;
  68. constVal = 0;
  69. constToStageArray.push_back(constNum);
  70. constToStageArray.push_back(stage);
  71. constToStageArray.push_back(constVal);
  72. }
  73. else
  74. {
  75. int constUsed = (*iter).second;
  76. if (constUsed >= 1)
  77. return false;
  78. else // const0 has been used, so use const1 for this stage.
  79. {
  80. std::pair<int,int> temp;
  81. temp.first = stage;
  82. temp.second = 1;
  83. constToStageAndConstMap[constNum] = temp;
  84. stageToConstMap[stage] = 1;
  85. constVal = 1;
  86. constToStageArray.push_back(constNum);
  87. constToStageArray.push_back(stage);
  88. constToStageArray.push_back(constVal);
  89. }
  90. }
  91. }
  92. constVal += GL_CONSTANT_COLOR0_NV;
  93. return true;
  94. }
  95. bool IsLegalTarget(int target)
  96. {
  97. if (target == GL_TEXTURE_CUBE_MAP_ARB)
  98. return true;
  99. if (target == GL_TEXTURE_3D)
  100. return true;
  101. #if defined(GL_EXT_texture_rectangle)
  102. if (target == GL_TEXTURE_RECTANGLE_EXT)
  103. return true;
  104. #elif defined(GL_NV_texture_rectangle)
  105. if (target == GL_TEXTURE_RECTANGLE_NV)
  106. return true;
  107. #endif
  108. if (target == GL_TEXTURE_2D)
  109. return true;
  110. if (target == GL_TEXTURE_1D)
  111. return true;
  112. return false;
  113. }
  114. bool ps10_set_map(const std::vector<int>& argv)
  115. {
  116. if (argv.size() % 2 != 0)
  117. {
  118. errors.set("Odd number of arguments for texture target map.");
  119. return false;
  120. }
  121. for (unsigned int i=0;i<argv.size();i=i+2)
  122. {
  123. int stage = argv[i];
  124. int target = argv[i+1];
  125. if (!IsLegalTarget(target))
  126. {
  127. errors.set("Illegal target in texture target map.");
  128. return false;
  129. }
  130. ps10::stageToTargetMap[stage] = target;
  131. }
  132. return true;
  133. }
  134. int const_to_combiner_reg_mapping[32][3]; // each 3 tuple is: (constant#, stage #, reg #)
  135. int const_to_combiner_reg_mapping_count = 0;
  136. namespace
  137. {
  138. struct set_constants
  139. {
  140. void operator() (constdef c)
  141. {
  142. if(c.reg[0] != 'c' && c.reg.size() != 2)
  143. DBG_MESG("def line must use constant registers", 0);
  144. int reg = c.reg[1] - '0';
  145. GLenum stage = GL_COMBINER0_NV + (reg / 2);
  146. GLenum cclr = GL_CONSTANT_COLOR0_NV + (reg % 2);
  147. GLfloat cval[4];
  148. cval[0] = c.r;
  149. cval[1] = c.g;
  150. cval[2] = c.b;
  151. cval[3] = c.a;
  152. glCombinerStageParameterfvNV(stage, cclr, cval);
  153. }
  154. };
  155. GLenum get_tex_target(int stage)
  156. {
  157. std::map<int, GLenum>::iterator iter = stageToTargetMap.find(stage);
  158. if (iter != stageToTargetMap.end())
  159. return (*iter).second;
  160. // If no mapping set, use the current state. This will not work correctly, in general,
  161. // if nvparse was invoked within a display list.
  162. if(glIsEnabled(GL_TEXTURE_CUBE_MAP_ARB))
  163. return GL_TEXTURE_CUBE_MAP_ARB;
  164. if(glIsEnabled(GL_TEXTURE_3D))
  165. return GL_TEXTURE_3D;
  166. #if defined(GL_EXT_texture_rectangle)
  167. if(glIsEnabled(GL_TEXTURE_RECTANGLE_EXT))
  168. return GL_TEXTURE_RECTANGLE_EXT;
  169. #elif defined(GL_NV_texture_rectangle)
  170. if(glIsEnabled(GL_TEXTURE_RECTANGLE_NV))
  171. return GL_TEXTURE_RECTANGLE_NV;
  172. #endif
  173. if(glIsEnabled(GL_TEXTURE_2D))
  174. return GL_TEXTURE_2D;
  175. if(glIsEnabled(GL_TEXTURE_1D))
  176. return GL_TEXTURE_1D;
  177. //otherwise make the op none...
  178. return GL_NONE;
  179. }
  180. struct set_texture_shaders
  181. {
  182. set_texture_shaders(vector<constdef> * cdef)
  183. {
  184. for(stage = 0; stage < 4; stage++)
  185. {
  186. glActiveTextureARB(GL_TEXTURE0_ARB + stage);
  187. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
  188. }
  189. stage = 0;
  190. c = cdef;
  191. }
  192. void operator() (vector<string> & instr)
  193. {
  194. if(stage > 3)
  195. return;
  196. glActiveTextureARB(GL_TEXTURE0_ARB + stage);
  197. string op = instr[0];
  198. if(op == "tex")
  199. {
  200. if(instr.size() != 2)
  201. fprintf(stderr,"incorrect \"tex\" instruction, stage %d...\n", stage);
  202. reg2stage[instr[1]] = stage;
  203. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, get_tex_target(stage));
  204. }
  205. else if(op == "texbem")
  206. {
  207. if(instr.size() != 3 || stage == 0)
  208. fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
  209. reg2stage[instr[1]] = stage;
  210. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
  211. if(reg2stage.count(instr[2]) == 0)
  212. fprintf(stderr,"incorrect \"texbem\" instruction, stage %d...\n", stage);
  213. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  214. }
  215. else if(op == "texbeml")
  216. {
  217. if(instr.size() != 3 || stage == 0)
  218. fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
  219. reg2stage[instr[1]] = stage;
  220. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_SCALE_NV);
  221. if(reg2stage.count(instr[2]) == 0)
  222. fprintf(stderr,"incorrect \"texbeml\" instruction, stage %d...\n", stage);
  223. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  224. }
  225. else if(op == "texcoord")
  226. {
  227. if(instr.size() != 2)
  228. fprintf(stderr,"incorrect \"texcoord\" instruction, stage %d...\n", stage);
  229. reg2stage[instr[1]] = stage;
  230. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_PASS_THROUGH_NV);
  231. }
  232. else if(op == "texkill")
  233. {
  234. if(instr.size() != 2)
  235. fprintf(stderr,"incorrect \"texkill\" instruction, stage %d...\n", stage);
  236. reg2stage[instr[1]] = stage;
  237. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_CULL_FRAGMENT_NV);
  238. }
  239. else if(op == "texm3x2pad")
  240. {
  241. if(instr.size() != 3 || stage == 0)
  242. fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
  243. reg2stage[instr[1]] = stage;
  244. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
  245. if(instr[2].find("_bx2") != string::npos)
  246. {
  247. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  248. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  249. }
  250. if(reg2stage.count(instr[2]) == 0)
  251. fprintf(stderr,"incorrect \"texm3x2pad\" instruction, stage %d...\n", stage);
  252. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  253. }
  254. else if(op == "texm3x2tex")
  255. {
  256. if(instr.size() != 3 || stage == 0)
  257. fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
  258. reg2stage[instr[1]] = stage;
  259. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_2D_NV);
  260. if(instr[2].find("_bx2") != string::npos)
  261. {
  262. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  263. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  264. }
  265. if(reg2stage.count(instr[2]) == 0)
  266. fprintf(stderr,"incorrect \"texm3x2tex\" instruction, stage %d...\n", stage);
  267. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  268. }
  269. else if(op == "texm3x3pad")
  270. {
  271. if(instr.size() != 3 || stage == 0)
  272. fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
  273. reg2stage[instr[1]] = stage;
  274. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_NV);
  275. if(instr[2].find("_bx2") != string::npos)
  276. {
  277. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  278. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  279. }
  280. if(reg2stage.count(instr[2]) == 0)
  281. fprintf(stderr,"incorrect \"texm3x3pad\" instruction, stage %d...\n", stage);
  282. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  283. }
  284. else if(op == "texm3x3tex")
  285. {
  286. if(instr.size() != 3 || stage == 0)
  287. fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
  288. reg2stage[instr[1]] = stage;
  289. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV);
  290. if(instr[2].find("_bx2") != string::npos)
  291. {
  292. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  293. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  294. }
  295. if(reg2stage.count(instr[2]) == 0)
  296. fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
  297. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  298. }
  299. else if(op == "texm3x3spec")
  300. {
  301. if(instr.size() != 4 || stage == 0)
  302. fprintf(stderr,"incorrect \"texm3x3spec\" instruction, stage %d...\n", stage);
  303. reg2stage[instr[1]] = stage;
  304. if(! c)
  305. return;
  306. constdef cd;
  307. for(int i = c->size()-1; i >= 0; i--)
  308. {
  309. cd = (*c)[i];
  310. if(cd.reg == "c0")
  311. break;
  312. }
  313. if(cd.reg != "c0" || instr[3] != "c0")
  314. return;
  315. GLfloat eye[4];
  316. eye[0] = cd.r;
  317. eye[1] = cd.g;
  318. eye[2] = cd.b;
  319. eye[3] = cd.a;
  320. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV);
  321. glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_CONST_EYE_NV, eye);
  322. if(instr[2].find("_bx2") != string::npos)
  323. {
  324. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  325. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  326. }
  327. if(reg2stage.count(instr[2]) == 0)
  328. fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
  329. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  330. }
  331. else if(op == "texm3x3vspec")
  332. {
  333. if(instr.size() != 3 || stage == 0)
  334. fprintf(stderr,"incorrect \"texm3x3vspec\" instruction, stage %d...\n", stage);
  335. reg2stage[instr[1]] = stage;
  336. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV);
  337. if(instr[2].find("_bx2") != string::npos)
  338. {
  339. instr[2].erase(instr[2].begin() + instr[2].find("_bx2"), instr[2].end());
  340. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV, GL_EXPAND_NORMAL_NV);
  341. }
  342. if(reg2stage.count(instr[2]) == 0)
  343. fprintf(stderr,"incorrect \"texm3x3tex\" instruction, stage %d...\n", stage);
  344. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  345. }
  346. else if(op == "texreg2ar")
  347. {
  348. if(instr.size() != 3 || stage == 0)
  349. fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
  350. reg2stage[instr[1]] = stage;
  351. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_AR_TEXTURE_2D_NV);
  352. if(reg2stage.count(instr[2]) == 0)
  353. fprintf(stderr,"incorrect \"texreg2ar\" instruction, stage %d...\n", stage);
  354. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  355. }
  356. else if(op == "texreg2gb")
  357. {
  358. if(instr.size() != 3 || stage == 0)
  359. fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
  360. reg2stage[instr[1]] = stage;
  361. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_DEPENDENT_GB_TEXTURE_2D_NV);
  362. if(reg2stage.count(instr[2]) == 0)
  363. fprintf(stderr,"incorrect \"texreg2gb\" instruction, stage %d...\n", stage);
  364. glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB + reg2stage[instr[2]]);
  365. }
  366. stage++;
  367. }
  368. map<string, int> reg2stage;
  369. int stage;
  370. vector<constdef> * c;
  371. };
  372. GLenum reg_enum(string s, int stage)
  373. {
  374. /*if(s == "c0")
  375. return GL_CONSTANT_COLOR0_NV;
  376. else if(s == "c1")
  377. return GL_CONSTANT_COLOR1_NV;
  378. else if(s == "c2")
  379. return GL_CONSTANT_COLOR0_NV;
  380. else if(s == "c3")
  381. return GL_CONSTANT_COLOR1_NV;
  382. else if(s == "c4")
  383. return GL_CONSTANT_COLOR0_NV;
  384. else if(s == "c5")
  385. return GL_CONSTANT_COLOR1_NV;
  386. else if(s == "c6")
  387. return GL_CONSTANT_COLOR0_NV;
  388. else if(s == "c7")
  389. return GL_CONSTANT_COLOR1_NV;
  390. */
  391. if (s == "c0" || s == "c1" || s == "c2" || s == "c3" ||
  392. s == "c4" || s == "c5" || s == "c6" || s == "c7")
  393. {
  394. GLenum result;
  395. if (!AddToMap(s,stage,result))
  396. errors.set("Illegal constant usage.",line_number);
  397. // This is a pain, since the caller is a void and no check is made for errors. Sigh.
  398. return result;
  399. }
  400. else if(s == "t0")
  401. return GL_TEXTURE0_ARB;
  402. else if(s == "t1")
  403. return GL_TEXTURE1_ARB;
  404. else if(s == "t2")
  405. return GL_TEXTURE2_ARB;
  406. else if(s == "t3")
  407. return GL_TEXTURE3_ARB;
  408. else if(s == "v0")
  409. return GL_PRIMARY_COLOR_NV;
  410. else if(s == "v1")
  411. return GL_SECONDARY_COLOR_NV;
  412. else if(s == "r0")
  413. return GL_SPARE0_NV;
  414. else if(s == "r1")
  415. return GL_SPARE1_NV;
  416. else // ??
  417. return GL_DISCARD_NV;
  418. }
  419. struct src
  420. {
  421. src(string s, int stage, string *regname=NULL)
  422. {
  423. init(s, stage, regname);
  424. }
  425. void init(string s, int stage, string *regname=NULL)
  426. {
  427. arg = s;
  428. comp = GL_RGB;
  429. alphaComp = GL_ALPHA;
  430. map = GL_SIGNED_IDENTITY_NV;
  431. unsigned int offset;
  432. if(
  433. (offset = s.find(".a")) != string::npos ||
  434. (offset = s.find(".w")) != string::npos
  435. )
  436. {
  437. comp = GL_ALPHA;
  438. s.erase(offset, offset+2);
  439. }
  440. else if ((offset = s.find(".b")) != string::npos ||
  441. (offset = s.find(".z")) != string::npos)
  442. {
  443. alphaComp = GL_BLUE;
  444. s.erase(offset,offset+2);
  445. }
  446. bool negate = false;
  447. if(s[0] == '1')
  448. {
  449. s.erase(0, 1);
  450. while(s[0] == ' ')
  451. s.erase(0,1);
  452. if(s[0] == '-')
  453. s.erase(0,1);
  454. while(s[0] == ' ')
  455. s.erase(0,1);
  456. map = GL_UNSIGNED_INVERT_NV;
  457. }
  458. else if(s[0] == '-')
  459. {
  460. s.erase(0, 1);
  461. while(s[0] == ' ')
  462. s.erase(0,1);
  463. negate = true;
  464. map = GL_UNSIGNED_INVERT_NV;
  465. }
  466. bool half_bias = false;
  467. bool expand = false;
  468. if(s.find("_bias") != string::npos)
  469. {
  470. s.erase(s.find("_bias"), 5);
  471. half_bias = true;
  472. }
  473. else if(s.find("_bx2") != string::npos)
  474. {
  475. s.erase(s.find("_bx2"), 4);
  476. expand = true;
  477. }
  478. if(expand)
  479. {
  480. if(negate)
  481. map = GL_EXPAND_NEGATE_NV;
  482. else
  483. map = GL_EXPAND_NORMAL_NV;
  484. }
  485. else if(half_bias)
  486. {
  487. if(negate)
  488. map = GL_HALF_BIAS_NEGATE_NV;
  489. else
  490. map = GL_HALF_BIAS_NORMAL_NV;
  491. }
  492. reg = reg_enum(s,stage);
  493. if (regname != NULL)
  494. *regname = s; // return the bare register name
  495. //alphaComp = GL_ALPHA;
  496. std::set<const char*, ltstr>::iterator iter =
  497. ps10::alphaBlueRegisters.find(s.c_str());
  498. if (iter != ps10::alphaBlueRegisters.end())
  499. alphaComp = GL_BLUE;
  500. }
  501. string arg;
  502. GLenum reg;
  503. GLenum map;
  504. GLenum comp;
  505. GLenum alphaComp;
  506. };
  507. struct set_register_combiners
  508. {
  509. set_register_combiners()
  510. {
  511. // combiner = 0;
  512. combiner = -1;
  513. }
  514. void operator() (vector<string> & instr)
  515. {
  516. string op;
  517. GLenum scale = GL_NONE;
  518. bool op_sat = false;
  519. bool paired_instr = false;
  520. int instr_base = 0;
  521. if (instr[0]=="+") {
  522. paired_instr = true;
  523. instr_base = 1;
  524. }
  525. op = instr[instr_base];
  526. unsigned int offset;
  527. if((offset = op.find("_x2")) != string::npos)
  528. {
  529. scale = GL_SCALE_BY_TWO_NV;
  530. op.erase(op.begin()+offset, op.begin()+offset+3);
  531. }
  532. else if((offset = op.find("_x4")) != string::npos)
  533. {
  534. scale = GL_SCALE_BY_FOUR_NV;
  535. op.erase(op.begin()+offset, op.begin()+offset+3);
  536. }
  537. else if((offset = op.find("_d2")) != string::npos)
  538. {
  539. scale = GL_SCALE_BY_ONE_HALF_NV;
  540. op.erase(op.begin()+offset, op.begin()+offset+3);
  541. }
  542. if((offset = op.find("_sat")) != string::npos)
  543. {
  544. // need to actually use this...
  545. op_sat = true;
  546. op.erase(op.begin()+offset, op.begin()+offset+4);
  547. }
  548. string dst = instr[1+instr_base];
  549. int mask = GL_RGBA;
  550. if(
  551. (offset = dst.find(".rgba")) != string::npos ||
  552. (offset = dst.find(".xyzw")) != string::npos
  553. )
  554. {
  555. dst.erase(offset, offset + 5);
  556. }
  557. else if(
  558. (offset = dst.find(".rgb")) != string::npos ||
  559. (offset = dst.find(".xyz")) != string::npos
  560. )
  561. {
  562. dst.erase(offset, offset + 4);
  563. mask = GL_RGB;
  564. }
  565. else if(
  566. (offset = dst.find(".a")) != string::npos ||
  567. (offset = dst.find(".w")) != string::npos
  568. )
  569. {
  570. dst.erase(offset, offset + 2);
  571. mask = GL_ALPHA;
  572. }
  573. if (!paired_instr)
  574. combiner++;
  575. GLenum dreg = reg_enum(dst,combiner);
  576. GLenum C = GL_COMBINER0_NV + combiner;
  577. bool isAlphaBlue = false; // To keep track of whether the dst register's alpha was its blue value.
  578. if(op == "add" || op == "sub")
  579. {
  580. src a(instr[2+instr_base],combiner);
  581. src b(instr[3+instr_base],combiner);
  582. if(mask == GL_RGBA || mask == GL_RGB)
  583. {
  584. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  585. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  586. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
  587. if(op == "add")
  588. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  589. else
  590. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_RGB);
  591. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  592. GL_FALSE, GL_FALSE, GL_FALSE);
  593. }
  594. else if (!paired_instr)
  595. {
  596. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  597. GL_FALSE, GL_FALSE, GL_FALSE);
  598. }
  599. if(mask == GL_RGBA || mask == GL_ALPHA)
  600. {
  601. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
  602. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  603. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp);
  604. if(op == "add")
  605. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  606. else
  607. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_EXPAND_NORMAL_NV, GL_ALPHA);
  608. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  609. GL_FALSE, GL_FALSE, GL_FALSE);
  610. }
  611. else if (!paired_instr)
  612. {
  613. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  614. GL_FALSE, GL_FALSE, GL_FALSE);
  615. }
  616. }
  617. else if(op == "cnd")
  618. {
  619. src a(instr[3+instr_base],combiner);
  620. src b(instr[4+instr_base],combiner);
  621. if(instr[2+instr_base] != "r0.a" && instr[2+instr_base] != "r0.w")
  622. {} // bad
  623. if(mask == GL_RGBA || mask == GL_RGB)
  624. {
  625. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  626. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  627. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, b.reg, b.map, b.comp);
  628. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  629. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  630. GL_FALSE, GL_FALSE, GL_TRUE);
  631. }
  632. else if (!paired_instr)
  633. {
  634. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  635. GL_FALSE, GL_FALSE, GL_FALSE);
  636. }
  637. if(mask == GL_RGBA || mask == GL_ALPHA)
  638. {
  639. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
  640. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  641. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, b.reg, b.map, b.alphaComp);
  642. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  643. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  644. GL_FALSE, GL_FALSE, GL_TRUE);
  645. }
  646. else if (!paired_instr)
  647. {
  648. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  649. GL_FALSE, GL_FALSE, GL_FALSE);
  650. }
  651. }
  652. else if(op == "dp3")
  653. {
  654. src a(instr[2+instr_base],combiner);
  655. src b(instr[3+instr_base],combiner);
  656. if(mask == GL_RGBA || mask == GL_RGB)
  657. {
  658. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  659. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
  660. glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
  661. GL_TRUE, GL_FALSE, GL_FALSE);
  662. }
  663. else if (!paired_instr)
  664. {
  665. // ooh.. what to do here?
  666. }
  667. if(mask == GL_RGBA || mask == GL_ALPHA)
  668. {
  669. // todo -- make next ref to dst.a actually ref dst.b since combiners can't write dp3 to the alpha channel
  670. // Done by Ashu: Put this register in the alphaBlueRegister set.
  671. isAlphaBlue = true;
  672. ps10::alphaBlueRegisters.insert(dst.c_str());
  673. }
  674. else if (!paired_instr)
  675. {
  676. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  677. GL_FALSE, GL_FALSE, GL_FALSE);
  678. }
  679. }
  680. else if(op == "lrp")
  681. {
  682. src a(instr[2+instr_base],combiner);
  683. src b(instr[3+instr_base],combiner);
  684. src c(instr[4+instr_base],combiner);
  685. if(mask == GL_RGBA || mask == GL_RGB)
  686. {
  687. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.comp);
  688. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
  689. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.comp);
  690. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
  691. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  692. GL_FALSE, GL_FALSE, GL_FALSE);
  693. }
  694. else if (!paired_instr)
  695. {
  696. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  697. GL_FALSE, GL_FALSE, GL_FALSE);
  698. }
  699. if(mask == GL_RGBA || mask == GL_ALPHA)
  700. {
  701. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, GL_UNSIGNED_IDENTITY_NV, a.alphaComp);
  702. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
  703. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, a.reg, GL_UNSIGNED_INVERT_NV, a.alphaComp);
  704. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp);
  705. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  706. GL_FALSE, GL_FALSE, GL_FALSE);
  707. }
  708. else if (!paired_instr)
  709. {
  710. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  711. GL_FALSE, GL_FALSE, GL_FALSE);
  712. }
  713. }
  714. else if(op == "mad")
  715. {
  716. src a(instr[2+instr_base],combiner);
  717. src b(instr[3+instr_base],combiner);
  718. src c(instr[4+instr_base],combiner);
  719. if(mask == GL_RGBA || mask == GL_RGB)
  720. {
  721. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  722. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
  723. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  724. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_D_NV, c.reg, c.map, c.comp);
  725. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  726. GL_FALSE, GL_FALSE, GL_FALSE);
  727. }
  728. else if (!paired_instr)
  729. {
  730. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  731. GL_FALSE, GL_FALSE, GL_FALSE);
  732. }
  733. if(mask == GL_RGBA || mask == GL_ALPHA)
  734. {
  735. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
  736. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
  737. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  738. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_D_NV, c.reg, c.map, c.alphaComp);
  739. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, dreg, scale, GL_NONE,
  740. GL_FALSE, GL_FALSE, GL_FALSE);
  741. }
  742. else if (!paired_instr)
  743. {
  744. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  745. GL_FALSE, GL_FALSE, GL_FALSE);
  746. }
  747. }
  748. else if(op == "mov")
  749. {
  750. src a(instr[2+instr_base],combiner);
  751. if(mask == GL_RGBA || mask == GL_RGB)
  752. {
  753. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  754. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_RGB);
  755. glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
  756. GL_FALSE, GL_FALSE, GL_FALSE);
  757. }
  758. else if (!paired_instr)
  759. {
  760. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  761. GL_FALSE, GL_FALSE, GL_FALSE);
  762. }
  763. if(mask == GL_RGBA || mask == GL_ALPHA)
  764. {
  765. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
  766. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA);
  767. glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
  768. GL_FALSE, GL_FALSE, GL_FALSE);
  769. }
  770. else if (!paired_instr)
  771. {
  772. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  773. GL_FALSE, GL_FALSE, GL_FALSE);
  774. }
  775. }
  776. else if(op == "mul")
  777. {
  778. src a(instr[2+instr_base],combiner);
  779. src b(instr[3+instr_base],combiner);
  780. if(mask == GL_RGBA || mask == GL_RGB)
  781. {
  782. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_A_NV, a.reg, a.map, a.comp);
  783. glCombinerInputNV(C, GL_RGB, GL_VARIABLE_B_NV, b.reg, b.map, b.comp);
  784. glCombinerOutputNV(C, GL_RGB, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
  785. GL_FALSE, GL_FALSE, GL_FALSE);
  786. }
  787. else if (!paired_instr)
  788. {
  789. glCombinerOutputNV(C, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  790. GL_FALSE, GL_FALSE, GL_FALSE);
  791. }
  792. if(mask == GL_RGBA || mask == GL_ALPHA)
  793. {
  794. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_A_NV, a.reg, a.map, a.alphaComp);
  795. glCombinerInputNV(C, GL_ALPHA, GL_VARIABLE_B_NV, b.reg, b.map, b.alphaComp);
  796. glCombinerOutputNV(C, GL_ALPHA, dreg, GL_DISCARD_NV, GL_DISCARD_NV, scale, GL_NONE,
  797. GL_FALSE, GL_FALSE, GL_FALSE);
  798. }
  799. else if (!paired_instr)
  800. {
  801. glCombinerOutputNV(C, GL_ALPHA, GL_DISCARD_NV, GL_DISCARD_NV, GL_DISCARD_NV, GL_NONE, GL_NONE,
  802. GL_FALSE, GL_FALSE, GL_FALSE);
  803. }
  804. }
  805. // combiner++;
  806. if (!isAlphaBlue)
  807. RemoveFromAlphaBlue(dst);
  808. }
  809. int combiner;
  810. };
  811. }
  812. void ps10::SetFinalCombinerStage()
  813. {
  814. glFinalCombinerInputNV(GL_VARIABLE_A_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_ALPHA);
  815. glFinalCombinerInputNV(GL_VARIABLE_B_NV,GL_SPARE0_NV,
  816. GL_UNSIGNED_IDENTITY_NV,GL_RGB);
  817. glFinalCombinerInputNV(GL_VARIABLE_C_NV,GL_FOG,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
  818. glFinalCombinerInputNV(GL_VARIABLE_D_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
  819. glFinalCombinerInputNV(GL_VARIABLE_E_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
  820. glFinalCombinerInputNV(GL_VARIABLE_F_NV,GL_ZERO,GL_UNSIGNED_IDENTITY_NV,GL_RGB);
  821. std::set<const char*, ltstr>::iterator iter = ps10::alphaBlueRegisters.find("r0");
  822. GLenum alphaComp = GL_ALPHA;
  823. if (iter != ps10::alphaBlueRegisters.end())
  824. alphaComp = GL_BLUE;
  825. glFinalCombinerInputNV(GL_VARIABLE_G_NV,GL_SPARE0_NV,GL_UNSIGNED_IDENTITY_NV,alphaComp);
  826. // We can now clear alphaBlueRegisters for the next go around
  827. alphaBlueRegisters.clear();
  828. }
  829. void ps10::invoke(vector<constdef> * c,
  830. list<vector<string> > * a,
  831. list<vector<string> > * b)
  832. {
  833. const_to_combiner_reg_mapping_count = 0; // Hansong
  834. glEnable(GL_PER_STAGE_CONSTANTS_NV); // should we require apps to do this?
  835. if(c)
  836. for_each(c->begin(), c->end(), set_constants());
  837. if(a)
  838. for_each(a->begin(), a->end(), set_texture_shaders(c));
  839. glActiveTextureARB( GL_TEXTURE0_ARB );
  840. int numCombiners = 0;
  841. list<vector<string> >::iterator it = b->begin();
  842. for(; it!=b->end(); ++it) {
  843. if ( (*it)[0] != "+" )
  844. numCombiners++;
  845. }
  846. glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, numCombiners);
  847. if(b)
  848. for_each(b->begin(), b->end(), set_register_combiners());
  849. SetFinalCombinerStage();
  850. // We can clear the stageToTarget map now.
  851. stageToTargetMap.clear();
  852. }
  853. // simple identification - just look for magic substring
  854. // -- easy to break...
  855. bool is_ps10(const char * s)
  856. {
  857. if(strstr(s, "ps.1.0"))
  858. return true;
  859. if(strstr(s, "Ps.1.0"))
  860. return true;
  861. if(strstr(s, "ps.1.1"))
  862. return true;
  863. if(strstr(s, "Ps.1.1"))
  864. return true;
  865. return false;
  866. }
  867. bool ps10::init_extensions()
  868. {
  869. // register combiners
  870. static bool rcinit = false;
  871. if(rcinit == false)
  872. {
  873. /*
  874. if(! glh_init_extensions("GL_NV_register_combiners"))
  875. {
  876. errors.set("unable to initialize GL_NV_register_combiners\n");
  877. return false;
  878. }
  879. else
  880. {
  881. */
  882. rcinit = true;
  883. /*
  884. }
  885. */
  886. }
  887. // register combiners 2
  888. static bool rc2init = false;
  889. if(rc2init == false)
  890. {
  891. /*
  892. if( ! glh_init_extensions("GL_NV_register_combiners2"))
  893. {
  894. errors.set("unable to initialize GL_NV_register_combiners2\n");
  895. return false;
  896. }
  897. else
  898. {
  899. */
  900. rc2init = true;
  901. /*
  902. }
  903. */
  904. }
  905. static bool tsinit = 0;
  906. if (tsinit == false )
  907. {
  908. /*
  909. if(! glh_init_extensions( "GL_NV_texture_shader " "GL_ARB_multitexture " ))
  910. {
  911. errors.set("unable to initialize GL_NV_texture_shader\n");
  912. return false;
  913. }
  914. else
  915. {
  916. */
  917. tsinit = true;
  918. /*
  919. }
  920. */
  921. }
  922. constToStageAndConstMap.clear();
  923. constToStageArray.clear();
  924. stageToConstMap.clear();
  925. line_number = 1;
  926. return true;
  927. }
  928. const int* ps10_get_info(int* pcount)
  929. {
  930. if (pcount)
  931. *pcount = constToStageArray.size();
  932. return &(constToStageArray[0]);
  933. }