vcp1.0_impl.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. #include "nvparse_errors.h"
  2. #include "nvparse_externs.h"
  3. #include <string.h>
  4. #include <string>
  5. #include <ctype.h>
  6. #ifndef _WIN32
  7. # define strnicmp strncasecmp
  8. #endif
  9. using namespace std;
  10. namespace
  11. {
  12. void ParseVertexProgramConstants( GLenum target, char *instring);
  13. GLuint LookupTrackMatrix(char *matrixName);
  14. GLuint LookupTrackMatrixTransform(char *matrixTransformName);
  15. }
  16. bool is_vcp10(const char * s)
  17. {
  18. return ! strncmp(s, "!!VCP1.0", 8);
  19. }
  20. bool vcp10_init(char * s)
  21. {
  22. static int vpinit = 0;
  23. if (vpinit == 0 )
  24. {
  25. /*
  26. if(! glh_init_extensions("GL_NV_vertex_program"))
  27. {
  28. errors.set("unable to initialize GL_NV_vertex_program");
  29. return false;
  30. }
  31. else
  32. {
  33. */
  34. vpinit = 1;
  35. /*
  36. }
  37. */
  38. }
  39. errors.reset();
  40. line_number = 1;
  41. myin = s;
  42. return true;
  43. }
  44. int vcp10_parse()
  45. {
  46. // parse the constant declarations, setting their values in the GL.
  47. ParseVertexProgramConstants( GL_VERTEX_PROGRAM_NV, myin);
  48. return 0;
  49. }
  50. namespace
  51. {
  52. //.----------------------------------------------------------------------------.
  53. //| Function : ParseVertexProgramConstants |
  54. //| Description: Parse and set VP1.0 constant memory based on const |
  55. //| directives. |
  56. //| |
  57. //| Format : c[XX] = (x, y, z, w); # where XXX is an integer 0-95. |
  58. //| : c[XX] = TRACK(matrix, transform); # track a matrix |
  59. //.----------------------------------------------------------------------------.
  60. void ParseVertexProgramConstants(GLenum target, char *instring)
  61. {
  62. // don't overwrite the original string.
  63. char *tmpstring = new char[strlen(instring)+1];
  64. strcpy(tmpstring, instring);
  65. char lineSeparator[] = "\n";
  66. //char wordSeparator[] = " \t";
  67. char error[256];
  68. char dummy[256];
  69. char *token;
  70. //iterate over the lines in the string
  71. token = strtok(tmpstring, lineSeparator);
  72. // we assume the first line is the "!!VCP1.0 line".
  73. if (token != NULL)
  74. {
  75. token = strtok(NULL, lineSeparator);
  76. }
  77. int iLineCount = 1; // skip first line
  78. while (token != NULL)
  79. {
  80. iLineCount++;
  81. // if the first non-whitespace character is a #, this is a comment. Skip.
  82. if (!sscanf(token, " #%s", dummy))
  83. { // not a comment. Is it a constant?
  84. // strip whitespace from the beginning of the string
  85. int i;
  86. for (i = 0; i < (int)strlen(token) && isspace(token[i]); i++);
  87. token += i;
  88. if (strlen(token) > 0 && // this is not a blank line and
  89. !strnicmp(token, "c[", 2)) // the first word is of the form "c[xx]", so its a constant.
  90. {
  91. int iConstID;
  92. int iNumValuesAssigned;
  93. char c[6];
  94. iNumValuesAssigned = sscanf(token, " %c [ %d ] = %s ", &c[0], &iConstID, dummy);
  95. if (3 != iNumValuesAssigned || toupper(c[0]) != 'C')
  96. { // error in constant directive.
  97. sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
  98. errors.set(error);
  99. }
  100. else if (!strnicmp(dummy, "track", 5))
  101. { // this is a TrackMatrix directive
  102. char matrixName[256], matrixTransformName[256];
  103. // the series of %c's are to make sure "track(" doesn't get glommed onto the matrixName
  104. iNumValuesAssigned = sscanf(token,
  105. " %c [ %d ] = %c%c%c%c%c ( %s %s ) ;",
  106. &c[0], &iConstID, &c[1], &c[2], &c[3], &c[4], &c[5],
  107. matrixName, matrixTransformName);
  108. if (iNumValuesAssigned < 8)
  109. {
  110. sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
  111. errors.set(error);
  112. }
  113. else
  114. {
  115. char *buffer;
  116. if (9 == iNumValuesAssigned)
  117. {
  118. // just need to remove any junk from the matrix names and IDs.
  119. buffer = strstr(matrixName, ",");
  120. if (buffer)
  121. *buffer = 0;
  122. buffer = strstr(matrixTransformName, ")");
  123. if (buffer)
  124. *buffer = 0;
  125. }
  126. else // 8 == iNumValuesAssigned
  127. {
  128. // have to split the two names, since they both were put into the matrixName
  129. buffer = strstr(matrixName, ",");
  130. if (buffer)
  131. {
  132. strcpy(matrixTransformName, buffer + 1);
  133. *buffer = 0;
  134. // get rid of paren at end of transform name, if it is there
  135. buffer = strstr(matrixTransformName, ")");
  136. if (buffer)
  137. *buffer = 0;
  138. }
  139. else
  140. {
  141. sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
  142. errors.set(error);
  143. }
  144. }
  145. // constant ID must be modulo 4.
  146. if (0 != (iConstID % 4))
  147. {
  148. sprintf(error,
  149. "error at line %d \n\"%s\"\n\tglTrackMatrixNV address must be modulo 4\n",
  150. iLineCount, token);
  151. errors.set(error);
  152. }
  153. else if (iConstID < 0 || iConstID > 95)
  154. {
  155. sprintf(error,
  156. "error at line %d \n\"%s\"\n\tConstant address out of range\n",
  157. iLineCount, token);
  158. errors.set(error);
  159. }
  160. else
  161. {
  162. // get the enum values for the specified matrices
  163. GLuint iMatrixID = LookupTrackMatrix(matrixName);
  164. GLuint iTransformID = LookupTrackMatrixTransform(matrixTransformName);
  165. if (0 == iMatrixID)
  166. {
  167. sprintf(error,
  168. "error at line %d \n\"%s\"\n\tInvalid Matrix parameter in glTrackMatrixNV.\n",
  169. iLineCount, token);
  170. errors.set(error);
  171. }
  172. else if (0 == iTransformID)
  173. {
  174. sprintf(error,
  175. "error at line %d \n\"%s\"\n\tInvalid Transform parameter in glTrackMatrixNV\n",
  176. iLineCount, token);
  177. errors.set(error);
  178. }
  179. else
  180. {
  181. // untrack any currently tracked matrix
  182. glTrackMatrixNV(target, iConstID, GL_NONE, GL_IDENTITY_NV);
  183. // tell GL the matrix to track
  184. glTrackMatrixNV(target, iConstID, iMatrixID, iTransformID);
  185. }
  186. }
  187. }
  188. }
  189. else // this is a constant directive
  190. {
  191. float xyzw[4] = {0, 0, 0, 0};
  192. iNumValuesAssigned = sscanf(token,
  193. " %c [ %d ] = ( %f , %f , %f , %f ) ; ",
  194. &c[0], &iConstID, xyzw, xyzw + 1, xyzw + 2, xyzw + 3);
  195. if (6 != iNumValuesAssigned)
  196. { // error in constant directive.
  197. sprintf(error, "error at line %d \n\"%s\"\n", iLineCount, token);
  198. errors.set(error);
  199. }
  200. else if (iConstID < 0 || iConstID > 95)
  201. {
  202. sprintf(error,
  203. "error at line %d \n\"%s\"\n\tConstant address out of range\n",
  204. iLineCount, token);
  205. errors.set(error);
  206. }
  207. else
  208. {
  209. // Always set the closest matrix location to tracking NONE to avoid errors!
  210. glTrackMatrixNV(target, iConstID - (iConstID % 4), GL_NONE, GL_IDENTITY_NV);
  211. // tell GL the constant values
  212. glProgramParameter4fvNV(target, iConstID, xyzw);
  213. }
  214. }
  215. }
  216. }
  217. // get the next line
  218. token = strtok(NULL, lineSeparator);
  219. }
  220. }
  221. struct MatrixLookupEntry
  222. {
  223. string name;
  224. GLuint ID;
  225. };
  226. //.----------------------------------------------------------------------------.
  227. //| Function : LookupTrackMatrix |
  228. //| Description: Returns the enumerated matrix name given a valid string |
  229. //| or 0 if an unknown matrix is requested. |
  230. //.----------------------------------------------------------------------------.
  231. GLuint LookupTrackMatrix(char *matrixName)
  232. {
  233. static bool bFirstTime = true;
  234. static int iNumEntries = 14;
  235. static MatrixLookupEntry* matrixLookupTable = new MatrixLookupEntry[iNumEntries];
  236. if (bFirstTime) // build the lookup table
  237. {
  238. matrixLookupTable[0].name = "GL_NONE";
  239. matrixLookupTable[0].ID = GL_NONE;
  240. matrixLookupTable[1].name = "GL_MODELVIEW";
  241. matrixLookupTable[1].ID = GL_MODELVIEW;
  242. matrixLookupTable[2].name = "GL_PROJECTION";
  243. matrixLookupTable[2].ID = GL_PROJECTION;
  244. matrixLookupTable[3].name = "GL_TEXTURE";
  245. matrixLookupTable[3].ID = GL_TEXTURE;
  246. matrixLookupTable[4].name = "GL_COLOR";
  247. matrixLookupTable[4].ID = GL_COLOR;
  248. matrixLookupTable[5].name = "GL_MODELVIEW_PROJECTION_NV";
  249. matrixLookupTable[5].ID = GL_MODELVIEW_PROJECTION_NV;
  250. matrixLookupTable[6].name = "GL_MATRIX0_NV";
  251. matrixLookupTable[6].ID = GL_MATRIX0_NV;
  252. matrixLookupTable[7].name = "GL_MATRIX1_NV";
  253. matrixLookupTable[7].ID = GL_MATRIX1_NV;
  254. matrixLookupTable[8].name = "GL_MATRIX2_NV";
  255. matrixLookupTable[8].ID = GL_MATRIX2_NV;
  256. matrixLookupTable[9].name = "GL_MATRIX3_NV";
  257. matrixLookupTable[9].ID = GL_MATRIX3_NV;
  258. matrixLookupTable[10].name = "GL_MATRIX4_NV";
  259. matrixLookupTable[10].ID = GL_MATRIX4_NV;
  260. matrixLookupTable[11].name = "GL_MATRIX5_NV";
  261. matrixLookupTable[11].ID = GL_MATRIX5_NV;
  262. matrixLookupTable[12].name = "GL_MATRIX6_NV";
  263. matrixLookupTable[12].ID = GL_MATRIX6_NV;
  264. matrixLookupTable[13].name = "GL_MATRIX7_NV";
  265. matrixLookupTable[13].ID = GL_MATRIX7_NV;
  266. bFirstTime = false;
  267. }
  268. for (int i = 0; i < iNumEntries; i++)
  269. {
  270. if (!strcmp(matrixName, matrixLookupTable[i].name.c_str()))
  271. {
  272. return matrixLookupTable[i].ID;
  273. }
  274. }
  275. return 0;
  276. }
  277. //.----------------------------------------------------------------------------.
  278. //| Function : LookupTrackMatrixTransform |
  279. //| Description: Returns the enumerated matrix transform name given a valid |
  280. //| string name or 0 if an unknown transform is requested. |
  281. //.----------------------------------------------------------------------------.
  282. GLuint LookupTrackMatrixTransform(char *matrixTransformName)
  283. {
  284. static bool bFirstTime = true;
  285. static int iNumEntries = 4;
  286. static MatrixLookupEntry* transformLookupTable = new MatrixLookupEntry[iNumEntries];
  287. if (bFirstTime)
  288. {
  289. transformLookupTable[0].name = "GL_IDENTITY_NV";
  290. transformLookupTable[0].ID = GL_IDENTITY_NV;
  291. transformLookupTable[1].name = "GL_INVERSE_NV";
  292. transformLookupTable[1].ID = GL_INVERSE_NV;
  293. transformLookupTable[2].name = "GL_TRANSPOSE_NV";
  294. transformLookupTable[2].ID = GL_TRANSPOSE_NV;
  295. transformLookupTable[3].name = "GL_INVERSE_TRANSPOSE_NV";
  296. transformLookupTable[3].ID = GL_INVERSE_TRANSPOSE_NV;
  297. bFirstTime = false;
  298. }
  299. for (int i = 0; i < iNumEntries; i++)
  300. {
  301. if (!strcmp( matrixTransformName, transformLookupTable[i].name.c_str()))
  302. {
  303. return transformLookupTable[i].ID;
  304. }
  305. }
  306. return 0;
  307. }
  308. }