Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1923 lines
59 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: array.c
  3. *
  4. * OpenGL client side vertex array functions.
  5. *
  6. * Created: 1-30-1996
  7. * Author: Hock San Lee [hockl]
  8. *
  9. * Copyright (c) 1996 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "os.h"
  14. #include "glsbcltu.h"
  15. #include "glclt.h"
  16. #include "compsize.h"
  17. #include "glsize.h"
  18. #include "context.h"
  19. #include "global.h"
  20. #include "lcfuncs.h"
  21. void FASTCALL VA_ArrayElementB(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  22. void FASTCALL VA_ArrayElement_V2F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  23. void FASTCALL VA_ArrayElement_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  24. void FASTCALL VA_ArrayElement_C3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  25. void FASTCALL VA_ArrayElement_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  26. void FASTCALL VA_ArrayElement_C3F_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  27. void FASTCALL VA_ArrayElement_C4F_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  28. void FASTCALL VA_ArrayElement_T2F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  29. void FASTCALL VA_ArrayElement_T2F_C3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  30. void FASTCALL VA_ArrayElement_T2F_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  31. void FASTCALL VA_ArrayElement_T2F_C3F_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  32. void FASTCALL VA_ArrayElement_T2F_C4F_N3F_V3F_B(__GLcontext *gc, GLint firstVertex, GLint nVertices);
  33. void FASTCALL VA_ArrayElementBI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  34. void FASTCALL VA_ArrayElement_V2F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  35. void FASTCALL VA_ArrayElement_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  36. void FASTCALL VA_ArrayElement_C3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  37. void FASTCALL VA_ArrayElement_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  38. void FASTCALL VA_ArrayElement_C3F_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  39. void FASTCALL VA_ArrayElement_C4F_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  40. void FASTCALL VA_ArrayElement_T2F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  41. void FASTCALL VA_ArrayElement_T2F_C3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  42. void FASTCALL VA_ArrayElement_T2F_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  43. void FASTCALL VA_ArrayElement_T2F_C3F_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  44. void FASTCALL VA_ArrayElement_T2F_C4F_N3F_V3F_BI(__GLcontext *gc, GLint nVertices, VAMAP* indices);
  45. void FASTCALL VA_ArrayElement(__GLcontext *gc, GLint i);
  46. void FASTCALL VA_ArrayElement_V2F(__GLcontext *gc, GLint i);
  47. void FASTCALL VA_ArrayElement_V3F(__GLcontext *gc, GLint i);
  48. void FASTCALL VA_ArrayElement_C3F_V3F(__GLcontext *gc, GLint i);
  49. void FASTCALL VA_ArrayElement_N3F_V3F(__GLcontext *gc, GLint i);
  50. void FASTCALL VA_ArrayElement_C3F_N3F_V3F(__GLcontext *gc, GLint i);
  51. void FASTCALL VA_ArrayElement_C4F_N3F_V3F(__GLcontext *gc, GLint i);
  52. void FASTCALL VA_ArrayElement_T2F_V3F(__GLcontext *gc, GLint i);
  53. void FASTCALL VA_ArrayElement_T2F_C3F_V3F(__GLcontext *gc, GLint i);
  54. void FASTCALL VA_ArrayElement_T2F_N3F_V3F(__GLcontext *gc, GLint i);
  55. void FASTCALL VA_ArrayElement_T2F_C3F_N3F_V3F(__GLcontext *gc, GLint i);
  56. void FASTCALL VA_ArrayElement_T2F_C4F_N3F_V3F(__GLcontext *gc, GLint i);
  57. #define VAMASK_FORMAT_C3F \
  58. (VAMASK_COLOR_ENABLE_MASK | VAMASK_COLOR_SIZE_3 | VAMASK_COLOR_TYPE_FLOAT)
  59. #define VAMASK_FORMAT_C4F \
  60. (VAMASK_COLOR_ENABLE_MASK | VAMASK_COLOR_SIZE_4 | VAMASK_COLOR_TYPE_FLOAT)
  61. #define VAMASK_FORMAT_C4UB \
  62. (VAMASK_COLOR_ENABLE_MASK | VAMASK_COLOR_SIZE_4 | VAMASK_COLOR_TYPE_UBYTE)
  63. #define VAMASK_FORMAT_N3F \
  64. (VAMASK_NORMAL_ENABLE_MASK | VAMASK_NORMAL_TYPE_FLOAT)
  65. #define VAMASK_FORMAT_T2F \
  66. (VAMASK_TEXCOORD_ENABLE_MASK | VAMASK_TEXCOORD_SIZE_2 | VAMASK_TEXCOORD_TYPE_FLOAT)
  67. #define VAMASK_FORMAT_T4F \
  68. (VAMASK_TEXCOORD_ENABLE_MASK | VAMASK_TEXCOORD_SIZE_4 | VAMASK_TEXCOORD_TYPE_FLOAT)
  69. #define VAMASK_FORMAT_V2F \
  70. (VAMASK_VERTEX_ENABLE_MASK | VAMASK_VERTEX_SIZE_2 | VAMASK_VERTEX_TYPE_FLOAT)
  71. #define VAMASK_FORMAT_V3F \
  72. (VAMASK_VERTEX_ENABLE_MASK | VAMASK_VERTEX_SIZE_3 | VAMASK_VERTEX_TYPE_FLOAT)
  73. #define VAMASK_FORMAT_V4F \
  74. (VAMASK_VERTEX_ENABLE_MASK | VAMASK_VERTEX_SIZE_4 | VAMASK_VERTEX_TYPE_FLOAT)
  75. #define VAMASK_FORMAT_C3F_V3F \
  76. (VAMASK_FORMAT_C3F | VAMASK_FORMAT_V3F)
  77. #define VAMASK_FORMAT_N3F_V3F \
  78. (VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  79. #define VAMASK_FORMAT_C3F_N3F_V3F \
  80. (VAMASK_FORMAT_C3F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  81. #define VAMASK_FORMAT_C4F_N3F_V3F \
  82. (VAMASK_FORMAT_C4F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  83. #define VAMASK_FORMAT_T2F_V3F \
  84. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_V3F)
  85. #define VAMASK_FORMAT_T2F_C3F_V3F \
  86. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_C3F | VAMASK_FORMAT_V3F)
  87. #define VAMASK_FORMAT_T2F_N3F_V3F \
  88. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  89. #define VAMASK_FORMAT_T2F_C3F_N3F_V3F \
  90. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_C3F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  91. #define VAMASK_FORMAT_T2F_C4F_N3F_V3F \
  92. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_C4F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V3F)
  93. #define VAMASK_FORMAT_C4UB_V2F \
  94. (VAMASK_FORMAT_C4UB | VAMASK_FORMAT_V2F)
  95. #define VAMASK_FORMAT_C4UB_V3F \
  96. (VAMASK_FORMAT_C4UB | VAMASK_FORMAT_V3F)
  97. #define VAMASK_FORMAT_T4F_V4F \
  98. (VAMASK_FORMAT_T4F | VAMASK_FORMAT_V4F)
  99. #define VAMASK_FORMAT_T2F_C4UB_V3F \
  100. (VAMASK_FORMAT_T2F | VAMASK_FORMAT_C4UB | VAMASK_FORMAT_V3F)
  101. #define VAMASK_FORMAT_T4F_C4F_N3F_V4F \
  102. (VAMASK_FORMAT_T4F | VAMASK_FORMAT_C4F | VAMASK_FORMAT_N3F | VAMASK_FORMAT_V4F)
  103. // TYPE_ASSERT
  104. GLint __glTypeSize[] =
  105. {
  106. sizeof(GLbyte), // GL_BYTE
  107. sizeof(GLubyte), // GL_UNSIGNED_BYTE
  108. sizeof(GLshort), // GL_SHORT
  109. sizeof(GLushort), // GL_UNSIGNED_SHORT
  110. sizeof(GLint), // GL_INT
  111. sizeof(GLuint), // GL_UNSIGNED_INT
  112. sizeof(GLfloat), // GL_FLOAT
  113. 2, // GL_2_BYTES
  114. 3, // GL_3_BYTES
  115. 4, // GL_4_BYTES
  116. sizeof(GLdouble) // GL_DOUBLE
  117. };
  118. // ARRAY_TYPE_ASSERT
  119. GLuint vaEnable[] =
  120. {
  121. VAMASK_VERTEX_ENABLE_MASK, // GL_VERTEX_ARRAY
  122. VAMASK_NORMAL_ENABLE_MASK, // GL_NORMAL_ARRAY
  123. VAMASK_COLOR_ENABLE_MASK, // GL_COLOR_ARRAY
  124. VAMASK_INDEX_ENABLE_MASK, // GL_INDEX_ARRAY
  125. VAMASK_TEXCOORD_ENABLE_MASK, // GL_TEXTURE_COORD_ARRAY
  126. VAMASK_EDGEFLAG_ENABLE_MASK // GL_EDGE_FLAG_ARRAY
  127. };
  128. PFNGLVECTOR afnTexCoord[] =
  129. {
  130. (PFNGLVECTOR)glcltTexCoord1sv,
  131. (PFNGLVECTOR)glcltTexCoord1iv,
  132. (PFNGLVECTOR)glcltTexCoord1fv,
  133. (PFNGLVECTOR)glcltTexCoord1dv,
  134. (PFNGLVECTOR)glcltTexCoord2sv,
  135. (PFNGLVECTOR)glcltTexCoord2iv,
  136. (PFNGLVECTOR)glcltTexCoord2fv,
  137. (PFNGLVECTOR)glcltTexCoord2dv,
  138. (PFNGLVECTOR)glcltTexCoord3sv,
  139. (PFNGLVECTOR)glcltTexCoord3iv,
  140. (PFNGLVECTOR)glcltTexCoord3fv,
  141. (PFNGLVECTOR)glcltTexCoord3dv,
  142. (PFNGLVECTOR)glcltTexCoord4sv,
  143. (PFNGLVECTOR)glcltTexCoord4iv,
  144. (PFNGLVECTOR)glcltTexCoord4fv,
  145. (PFNGLVECTOR)glcltTexCoord4dv,
  146. };
  147. PFNGLVECTOR afnTexCoordCompile[] =
  148. {
  149. (PFNGLVECTOR)__gllc_TexCoord1sv,
  150. (PFNGLVECTOR)__gllc_TexCoord1iv,
  151. (PFNGLVECTOR)__gllc_TexCoord1fv,
  152. (PFNGLVECTOR)__gllc_TexCoord1dv,
  153. (PFNGLVECTOR)__gllc_TexCoord2sv,
  154. (PFNGLVECTOR)__gllc_TexCoord2iv,
  155. (PFNGLVECTOR)__gllc_TexCoord2fv,
  156. (PFNGLVECTOR)__gllc_TexCoord2dv,
  157. (PFNGLVECTOR)__gllc_TexCoord3sv,
  158. (PFNGLVECTOR)__gllc_TexCoord3iv,
  159. (PFNGLVECTOR)__gllc_TexCoord3fv,
  160. (PFNGLVECTOR)__gllc_TexCoord3dv,
  161. (PFNGLVECTOR)__gllc_TexCoord4sv,
  162. (PFNGLVECTOR)__gllc_TexCoord4iv,
  163. (PFNGLVECTOR)__gllc_TexCoord4fv,
  164. (PFNGLVECTOR)__gllc_TexCoord4dv,
  165. };
  166. PFNGLVECTOR afnColor_InRGBA[] =
  167. {
  168. (PFNGLVECTOR)glcltColor3bv_InRGBA,
  169. (PFNGLVECTOR)glcltColor3ubv_InRGBA,
  170. (PFNGLVECTOR)glcltColor3sv_InRGBA,
  171. (PFNGLVECTOR)glcltColor3usv_InRGBA,
  172. (PFNGLVECTOR)glcltColor3iv_InRGBA,
  173. (PFNGLVECTOR)glcltColor3uiv_InRGBA,
  174. (PFNGLVECTOR)glcltColor3fv_InRGBA,
  175. (PFNGLVECTOR)glcltColor3dv_InRGBA,
  176. (PFNGLVECTOR)glcltColor4bv_InRGBA,
  177. (PFNGLVECTOR)glcltColor4ubv_InRGBA,
  178. (PFNGLVECTOR)glcltColor4sv_InRGBA,
  179. (PFNGLVECTOR)glcltColor4usv_InRGBA,
  180. (PFNGLVECTOR)glcltColor4iv_InRGBA,
  181. (PFNGLVECTOR)glcltColor4uiv_InRGBA,
  182. (PFNGLVECTOR)glcltColor4fv_InRGBA,
  183. (PFNGLVECTOR)glcltColor4dv_InRGBA,
  184. };
  185. PFNGLVECTOR afnColor_InCI[] =
  186. {
  187. (PFNGLVECTOR)glcltColor3bv_InCI,
  188. (PFNGLVECTOR)glcltColor3ubv_InCI,
  189. (PFNGLVECTOR)glcltColor3sv_InCI,
  190. (PFNGLVECTOR)glcltColor3usv_InCI,
  191. (PFNGLVECTOR)glcltColor3iv_InCI,
  192. (PFNGLVECTOR)glcltColor3uiv_InCI,
  193. (PFNGLVECTOR)glcltColor3fv_InCI,
  194. (PFNGLVECTOR)glcltColor3dv_InCI,
  195. (PFNGLVECTOR)glcltColor4bv_InCI,
  196. (PFNGLVECTOR)glcltColor4ubv_InCI,
  197. (PFNGLVECTOR)glcltColor4sv_InCI,
  198. (PFNGLVECTOR)glcltColor4usv_InCI,
  199. (PFNGLVECTOR)glcltColor4iv_InCI,
  200. (PFNGLVECTOR)glcltColor4uiv_InCI,
  201. (PFNGLVECTOR)glcltColor4fv_InCI,
  202. (PFNGLVECTOR)glcltColor4dv_InCI,
  203. };
  204. PFNGLVECTOR afnColorCompile[] =
  205. {
  206. (PFNGLVECTOR)__gllc_Color3bv,
  207. (PFNGLVECTOR)__gllc_Color3ubv,
  208. (PFNGLVECTOR)__gllc_Color3sv,
  209. (PFNGLVECTOR)__gllc_Color3usv,
  210. (PFNGLVECTOR)__gllc_Color3iv,
  211. (PFNGLVECTOR)__gllc_Color3uiv,
  212. (PFNGLVECTOR)__gllc_Color3fv,
  213. (PFNGLVECTOR)__gllc_Color3dv,
  214. (PFNGLVECTOR)__gllc_Color4bv,
  215. (PFNGLVECTOR)__gllc_Color4ubv,
  216. (PFNGLVECTOR)__gllc_Color4sv,
  217. (PFNGLVECTOR)__gllc_Color4usv,
  218. (PFNGLVECTOR)__gllc_Color4iv,
  219. (PFNGLVECTOR)__gllc_Color4uiv,
  220. (PFNGLVECTOR)__gllc_Color4fv,
  221. (PFNGLVECTOR)__gllc_Color4dv,
  222. };
  223. PFNGLVECTOR afnIndex_InRGBA[] =
  224. {
  225. (PFNGLVECTOR)glcltIndexubv_InRGBA,
  226. (PFNGLVECTOR)glcltIndexsv_InRGBA,
  227. (PFNGLVECTOR)glcltIndexiv_InRGBA,
  228. (PFNGLVECTOR)glcltIndexfv_InRGBA,
  229. (PFNGLVECTOR)glcltIndexdv_InRGBA,
  230. };
  231. PFNGLVECTOR afnIndex_InCI[] =
  232. {
  233. (PFNGLVECTOR)glcltIndexubv_InCI,
  234. (PFNGLVECTOR)glcltIndexsv_InCI,
  235. (PFNGLVECTOR)glcltIndexiv_InCI,
  236. (PFNGLVECTOR)glcltIndexfv_InCI,
  237. (PFNGLVECTOR)glcltIndexdv_InCI,
  238. };
  239. PFNGLVECTOR afnIndexCompile[] =
  240. {
  241. (PFNGLVECTOR)__gllc_Indexubv,
  242. (PFNGLVECTOR)__gllc_Indexsv,
  243. (PFNGLVECTOR)__gllc_Indexiv,
  244. (PFNGLVECTOR)__gllc_Indexfv,
  245. (PFNGLVECTOR)__gllc_Indexdv,
  246. };
  247. PFNGLVECTOR afnNormal[] =
  248. {
  249. (PFNGLVECTOR)glcltNormal3bv,
  250. (PFNGLVECTOR)glcltNormal3sv,
  251. (PFNGLVECTOR)glcltNormal3iv,
  252. (PFNGLVECTOR)glcltNormal3fv,
  253. (PFNGLVECTOR)glcltNormal3dv,
  254. };
  255. PFNGLVECTOR afnNormalCompile[] =
  256. {
  257. (PFNGLVECTOR)__gllc_Normal3bv,
  258. (PFNGLVECTOR)__gllc_Normal3sv,
  259. (PFNGLVECTOR)__gllc_Normal3iv,
  260. (PFNGLVECTOR)__gllc_Normal3fv,
  261. (PFNGLVECTOR)__gllc_Normal3dv,
  262. };
  263. PFNGLVECTOR afnVertex[] =
  264. {
  265. (PFNGLVECTOR)glcltVertex2sv,
  266. (PFNGLVECTOR)glcltVertex2iv,
  267. (PFNGLVECTOR)glcltVertex2fv,
  268. (PFNGLVECTOR)glcltVertex2dv,
  269. (PFNGLVECTOR)glcltVertex3sv,
  270. (PFNGLVECTOR)glcltVertex3iv,
  271. (PFNGLVECTOR)glcltVertex3fv,
  272. (PFNGLVECTOR)glcltVertex3dv,
  273. (PFNGLVECTOR)glcltVertex4sv,
  274. (PFNGLVECTOR)glcltVertex4iv,
  275. (PFNGLVECTOR)glcltVertex4fv,
  276. (PFNGLVECTOR)glcltVertex4dv,
  277. };
  278. PFNGLVECTOR afnVertexCompile[] =
  279. {
  280. (PFNGLVECTOR)__gllc_Vertex2sv,
  281. (PFNGLVECTOR)__gllc_Vertex2iv,
  282. (PFNGLVECTOR)__gllc_Vertex2fv,
  283. (PFNGLVECTOR)__gllc_Vertex2dv,
  284. (PFNGLVECTOR)__gllc_Vertex3sv,
  285. (PFNGLVECTOR)__gllc_Vertex3iv,
  286. (PFNGLVECTOR)__gllc_Vertex3fv,
  287. (PFNGLVECTOR)__gllc_Vertex3dv,
  288. (PFNGLVECTOR)__gllc_Vertex4sv,
  289. (PFNGLVECTOR)__gllc_Vertex4iv,
  290. (PFNGLVECTOR)__gllc_Vertex4fv,
  291. (PFNGLVECTOR)__gllc_Vertex4dv,
  292. };
  293. void FASTCALL __glInitVertexArray(__GLcontext *gc)
  294. {
  295. // Initial vertex array state.
  296. static __GLvertexArray defaultVertexArrayState =
  297. {
  298. __GL_VERTEX_ARRAY_DIRTY, // flags
  299. VAMASK_TEXCOORD_SIZE_4 | // mask
  300. VAMASK_TEXCOORD_TYPE_FLOAT |
  301. VAMASK_INDEX_TYPE_FLOAT |
  302. VAMASK_COLOR_SIZE_4 |
  303. VAMASK_COLOR_TYPE_FLOAT |
  304. VAMASK_NORMAL_TYPE_FLOAT |
  305. VAMASK_VERTEX_SIZE_4 |
  306. VAMASK_VERTEX_TYPE_FLOAT,
  307. VA_ArrayElement, // pfnArrayElement
  308. VA_ArrayElementB, // pfnArrayElementBatch
  309. VA_ArrayElementBI, // pfnArrayElementBatchIndirect
  310. { // edgeFlag
  311. sizeof(GLboolean), // ibytes
  312. 0, // stride
  313. NULL, // pointer
  314. glcltEdgeFlagv, // pfn
  315. __gllc_EdgeFlagv, // pfnCompile
  316. },
  317. { // texcoord
  318. 4, // size
  319. GL_FLOAT, // type
  320. 4 * sizeof(GLfloat), // ibytes
  321. 0, // stride
  322. NULL, // pointer
  323. NULL, // pfn
  324. NULL, // pfnCompile
  325. },
  326. { // index
  327. GL_FLOAT, // type
  328. sizeof(GLfloat), // ibytes
  329. 0, // stride
  330. NULL, // pointer
  331. NULL, // pfn
  332. NULL, // pfnCompile
  333. },
  334. { // color
  335. 4, // size
  336. GL_FLOAT, // type
  337. 4 * sizeof(GLfloat), // ibytes
  338. 0, // stride
  339. NULL, // pointer
  340. NULL, // pfn
  341. NULL, // pfnCompile
  342. },
  343. { // normal
  344. GL_FLOAT, // type
  345. 3 * sizeof(GLfloat), // ibytes
  346. 0, // stride
  347. NULL, // pointer
  348. NULL, // pfn
  349. NULL, // pfnCompile
  350. },
  351. { // vertex
  352. 4, // size
  353. GL_FLOAT, // type
  354. 4 * sizeof(GLfloat), // ibytes
  355. 0, // stride
  356. NULL, // pointer
  357. NULL, // pfn
  358. NULL, // pfnCompile
  359. },
  360. };
  361. gc->vertexArray = defaultVertexArrayState;
  362. }
  363. void APIENTRY glcltEdgeFlagPointer (GLsizei stride, const GLvoid *pointer)
  364. {
  365. __GL_SETUP();
  366. // Not allowed in begin/end.
  367. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  368. {
  369. GLSETERROR(GL_INVALID_OPERATION);
  370. return;
  371. }
  372. if (stride < 0)
  373. {
  374. GLSETERROR(GL_INVALID_VALUE);
  375. return;
  376. }
  377. if (stride)
  378. gc->vertexArray.edgeFlag.ibytes = stride;
  379. else
  380. gc->vertexArray.edgeFlag.ibytes = sizeof(GLboolean);
  381. gc->vertexArray.edgeFlag.stride = stride;
  382. gc->vertexArray.edgeFlag.pointer = pointer;
  383. }
  384. void APIENTRY glcltTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
  385. {
  386. GLuint vaMask;
  387. __GL_SETUP();
  388. // Not allowed in begin/end.
  389. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  390. {
  391. GLSETERROR(GL_INVALID_OPERATION);
  392. return;
  393. }
  394. switch (type)
  395. {
  396. case GL_SHORT:
  397. vaMask = VAMASK_TEXCOORD_TYPE_SHORT;
  398. break;
  399. case GL_INT:
  400. vaMask = VAMASK_TEXCOORD_TYPE_INT;
  401. break;
  402. case GL_FLOAT:
  403. vaMask = VAMASK_TEXCOORD_TYPE_FLOAT;
  404. break;
  405. case GL_DOUBLE:
  406. vaMask = VAMASK_TEXCOORD_TYPE_DOUBLE;
  407. break;
  408. default:
  409. GLSETERROR(GL_INVALID_ENUM);
  410. return;
  411. }
  412. switch (size)
  413. {
  414. case 1:
  415. vaMask |= VAMASK_TEXCOORD_SIZE_1;
  416. break;
  417. case 2:
  418. vaMask |= VAMASK_TEXCOORD_SIZE_2;
  419. break;
  420. case 3:
  421. vaMask |= VAMASK_TEXCOORD_SIZE_3;
  422. break;
  423. case 4:
  424. vaMask |= VAMASK_TEXCOORD_SIZE_4;
  425. break;
  426. default:
  427. GLSETERROR(GL_INVALID_VALUE);
  428. return;
  429. }
  430. if (stride < 0)
  431. {
  432. GLSETERROR(GL_INVALID_VALUE);
  433. return;
  434. }
  435. if (stride)
  436. gc->vertexArray.texCoord.ibytes = stride;
  437. else
  438. gc->vertexArray.texCoord.ibytes = size * __GLTYPESIZE(type);
  439. gc->vertexArray.texCoord.size = size;
  440. gc->vertexArray.texCoord.type = type;
  441. gc->vertexArray.texCoord.stride = stride;
  442. gc->vertexArray.texCoord.pointer = pointer;
  443. if ((gc->vertexArray.mask & VAMASK_TEXCOORD_TYPE_SIZE_MASK) != vaMask)
  444. {
  445. gc->vertexArray.mask &= ~VAMASK_TEXCOORD_TYPE_SIZE_MASK;
  446. gc->vertexArray.mask |= vaMask;
  447. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  448. }
  449. }
  450. void APIENTRY glcltColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
  451. {
  452. GLuint vaMask;
  453. __GL_SETUP();
  454. // Not allowed in begin/end.
  455. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  456. {
  457. GLSETERROR(GL_INVALID_OPERATION);
  458. return;
  459. }
  460. switch (type)
  461. {
  462. case GL_BYTE:
  463. vaMask = VAMASK_COLOR_TYPE_BYTE;
  464. break;
  465. case GL_UNSIGNED_BYTE:
  466. vaMask = VAMASK_COLOR_TYPE_UBYTE;
  467. break;
  468. case GL_SHORT:
  469. vaMask = VAMASK_COLOR_TYPE_SHORT;
  470. break;
  471. case GL_UNSIGNED_SHORT:
  472. vaMask = VAMASK_COLOR_TYPE_USHORT;
  473. break;
  474. case GL_INT:
  475. vaMask = VAMASK_COLOR_TYPE_INT;
  476. break;
  477. case GL_UNSIGNED_INT:
  478. vaMask = VAMASK_COLOR_TYPE_UINT;
  479. break;
  480. case GL_FLOAT:
  481. vaMask = VAMASK_COLOR_TYPE_FLOAT;
  482. break;
  483. case GL_DOUBLE:
  484. vaMask = VAMASK_COLOR_TYPE_DOUBLE;
  485. break;
  486. default:
  487. GLSETERROR(GL_INVALID_ENUM);
  488. return;
  489. }
  490. switch (size)
  491. {
  492. case 3:
  493. vaMask |= VAMASK_COLOR_SIZE_3;
  494. break;
  495. case 4:
  496. vaMask |= VAMASK_COLOR_SIZE_4;
  497. break;
  498. default:
  499. GLSETERROR(GL_INVALID_VALUE);
  500. return;
  501. }
  502. if (stride < 0)
  503. {
  504. GLSETERROR(GL_INVALID_VALUE);
  505. return;
  506. }
  507. if (stride)
  508. gc->vertexArray.color.ibytes = stride;
  509. else
  510. gc->vertexArray.color.ibytes = size * __GLTYPESIZE(type);
  511. gc->vertexArray.color.size = size;
  512. gc->vertexArray.color.type = type;
  513. gc->vertexArray.color.stride = stride;
  514. gc->vertexArray.color.pointer = pointer;
  515. if ((gc->vertexArray.mask & VAMASK_COLOR_TYPE_SIZE_MASK) != vaMask)
  516. {
  517. gc->vertexArray.mask &= ~VAMASK_COLOR_TYPE_SIZE_MASK;
  518. gc->vertexArray.mask |= vaMask;
  519. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  520. }
  521. }
  522. void APIENTRY glcltIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
  523. {
  524. GLuint vaMask;
  525. __GL_SETUP();
  526. // Not allowed in begin/end.
  527. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  528. {
  529. GLSETERROR(GL_INVALID_OPERATION);
  530. return;
  531. }
  532. switch (type)
  533. {
  534. case GL_UNSIGNED_BYTE:
  535. vaMask = VAMASK_INDEX_TYPE_UBYTE;
  536. break;
  537. case GL_SHORT:
  538. vaMask = VAMASK_INDEX_TYPE_SHORT;
  539. break;
  540. case GL_INT:
  541. vaMask = VAMASK_INDEX_TYPE_INT;
  542. break;
  543. case GL_FLOAT:
  544. vaMask = VAMASK_INDEX_TYPE_FLOAT;
  545. break;
  546. case GL_DOUBLE:
  547. vaMask = VAMASK_INDEX_TYPE_DOUBLE;
  548. break;
  549. default:
  550. GLSETERROR(GL_INVALID_ENUM);
  551. return;
  552. }
  553. if (stride < 0)
  554. {
  555. GLSETERROR(GL_INVALID_VALUE);
  556. return;
  557. }
  558. if (stride)
  559. gc->vertexArray.index.ibytes = stride;
  560. else
  561. gc->vertexArray.index.ibytes = __GLTYPESIZE(type);
  562. gc->vertexArray.index.type = type;
  563. gc->vertexArray.index.stride = stride;
  564. gc->vertexArray.index.pointer = pointer;
  565. // update index function pointer!
  566. if ((gc->vertexArray.mask & VAMASK_INDEX_TYPE_SIZE_MASK) != vaMask)
  567. {
  568. gc->vertexArray.mask &= ~VAMASK_INDEX_TYPE_SIZE_MASK;
  569. gc->vertexArray.mask |= vaMask;
  570. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  571. }
  572. }
  573. void APIENTRY glcltNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
  574. {
  575. GLuint vaMask;
  576. __GL_SETUP();
  577. // Not allowed in begin/end.
  578. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  579. {
  580. GLSETERROR(GL_INVALID_OPERATION);
  581. return;
  582. }
  583. switch (type)
  584. {
  585. case GL_BYTE:
  586. vaMask = VAMASK_NORMAL_TYPE_BYTE;
  587. break;
  588. case GL_SHORT:
  589. vaMask = VAMASK_NORMAL_TYPE_SHORT;
  590. break;
  591. case GL_INT:
  592. vaMask = VAMASK_NORMAL_TYPE_INT;
  593. break;
  594. case GL_FLOAT:
  595. vaMask = VAMASK_NORMAL_TYPE_FLOAT;
  596. break;
  597. case GL_DOUBLE:
  598. vaMask = VAMASK_NORMAL_TYPE_DOUBLE;
  599. break;
  600. default:
  601. GLSETERROR(GL_INVALID_ENUM);
  602. return;
  603. }
  604. if (stride < 0)
  605. {
  606. GLSETERROR(GL_INVALID_VALUE);
  607. return;
  608. }
  609. if (stride)
  610. gc->vertexArray.normal.ibytes = stride;
  611. else
  612. gc->vertexArray.normal.ibytes = 3 * __GLTYPESIZE(type);
  613. gc->vertexArray.normal.type = type;
  614. gc->vertexArray.normal.stride = stride;
  615. gc->vertexArray.normal.pointer = pointer;
  616. if ((gc->vertexArray.mask & VAMASK_NORMAL_TYPE_SIZE_MASK) != vaMask)
  617. {
  618. gc->vertexArray.mask &= ~VAMASK_NORMAL_TYPE_SIZE_MASK;
  619. gc->vertexArray.mask |= vaMask;
  620. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  621. }
  622. }
  623. void APIENTRY glcltVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
  624. {
  625. GLuint vaMask;
  626. __GL_SETUP();
  627. // Not allowed in begin/end.
  628. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  629. {
  630. GLSETERROR(GL_INVALID_OPERATION);
  631. return;
  632. }
  633. switch (type)
  634. {
  635. case GL_SHORT:
  636. vaMask = VAMASK_VERTEX_TYPE_SHORT;
  637. break;
  638. case GL_INT:
  639. vaMask = VAMASK_VERTEX_TYPE_INT;
  640. break;
  641. case GL_FLOAT:
  642. vaMask = VAMASK_VERTEX_TYPE_FLOAT;
  643. break;
  644. case GL_DOUBLE:
  645. vaMask = VAMASK_VERTEX_TYPE_DOUBLE;
  646. break;
  647. default:
  648. GLSETERROR(GL_INVALID_ENUM);
  649. return;
  650. }
  651. switch (size)
  652. {
  653. case 2:
  654. vaMask |= VAMASK_VERTEX_SIZE_2;
  655. break;
  656. case 3:
  657. vaMask |= VAMASK_VERTEX_SIZE_3;
  658. break;
  659. case 4:
  660. vaMask |= VAMASK_VERTEX_SIZE_4;
  661. break;
  662. default:
  663. GLSETERROR(GL_INVALID_VALUE);
  664. return;
  665. }
  666. if (stride < 0)
  667. {
  668. GLSETERROR(GL_INVALID_VALUE);
  669. return;
  670. }
  671. if (stride)
  672. gc->vertexArray.vertex.ibytes = stride;
  673. else
  674. gc->vertexArray.vertex.ibytes = size * __GLTYPESIZE(type);
  675. gc->vertexArray.vertex.size = size;
  676. gc->vertexArray.vertex.type = type;
  677. gc->vertexArray.vertex.stride = stride;
  678. gc->vertexArray.vertex.pointer = pointer;
  679. if ((gc->vertexArray.mask & VAMASK_VERTEX_TYPE_SIZE_MASK) != vaMask)
  680. {
  681. gc->vertexArray.mask &= ~VAMASK_VERTEX_TYPE_SIZE_MASK;
  682. gc->vertexArray.mask |= vaMask;
  683. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  684. }
  685. }
  686. void APIENTRY glcltEnableClientState (GLenum cap)
  687. {
  688. __GL_SETUP();
  689. // Not allowed in begin/end.
  690. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  691. {
  692. GLSETERROR(GL_INVALID_OPERATION);
  693. return;
  694. }
  695. // ARRAY_TYPE_ASSERT
  696. if (RANGE(cap,GL_VERTEX_ARRAY,GL_EDGE_FLAG_ARRAY))
  697. {
  698. if (!(gc->vertexArray.mask & vaEnable[cap - GL_VERTEX_ARRAY]))
  699. {
  700. gc->vertexArray.mask |= vaEnable[cap - GL_VERTEX_ARRAY];
  701. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  702. }
  703. }
  704. }
  705. void APIENTRY glcltDisableClientState (GLenum cap)
  706. {
  707. __GL_SETUP();
  708. // Not allowed in begin/end.
  709. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  710. {
  711. GLSETERROR(GL_INVALID_OPERATION);
  712. return;
  713. }
  714. // ARRAY_TYPE_ASSERT
  715. if (RANGE(cap,GL_VERTEX_ARRAY,GL_EDGE_FLAG_ARRAY))
  716. {
  717. if (gc->vertexArray.mask & vaEnable[cap - GL_VERTEX_ARRAY])
  718. {
  719. gc->vertexArray.mask &= ~vaEnable[cap - GL_VERTEX_ARRAY];
  720. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  721. }
  722. }
  723. }
  724. void APIENTRY glcltGetPointerv (GLenum pname, GLvoid* *params)
  725. {
  726. __GL_SETUP();
  727. // Not allowed in begin/end.
  728. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  729. {
  730. GLSETERROR(GL_INVALID_OPERATION);
  731. return;
  732. }
  733. switch (pname)
  734. {
  735. case GL_VERTEX_ARRAY_POINTER:
  736. *params = (GLvoid *) gc->vertexArray.vertex.pointer;
  737. break;
  738. case GL_NORMAL_ARRAY_POINTER:
  739. *params = (GLvoid *) gc->vertexArray.normal.pointer;
  740. break;
  741. case GL_COLOR_ARRAY_POINTER:
  742. *params = (GLvoid *) gc->vertexArray.color.pointer;
  743. break;
  744. case GL_INDEX_ARRAY_POINTER:
  745. *params = (GLvoid *) gc->vertexArray.index.pointer;
  746. break;
  747. case GL_TEXTURE_COORD_ARRAY_POINTER:
  748. *params = (GLvoid *) gc->vertexArray.texCoord.pointer;
  749. break;
  750. case GL_EDGE_FLAG_ARRAY_POINTER:
  751. *params = (GLvoid *) gc->vertexArray.edgeFlag.pointer;
  752. break;
  753. case GL_SELECTION_BUFFER_POINTER:
  754. // The client pointer is maintained current at all times.
  755. *params = (GLvoid *) gc->select.resultBase;
  756. break;
  757. case GL_FEEDBACK_BUFFER_POINTER:
  758. // The client pointer is maintained current at all times.
  759. *params = (GLvoid *) gc->feedback.resultBase;
  760. break;
  761. default:
  762. GLSETERROR(GL_INVALID_ENUM);
  763. break;
  764. }
  765. }
  766. // We have special cases for the following formats. They also match the
  767. // special cases in display list.
  768. //
  769. // V2F
  770. // V3F
  771. // C3F_V3F
  772. // N3F_V3F
  773. // C3F_N3F_V3F (non 1.1 format)
  774. // C4F_N3F_V3F
  775. // T2F_V3F
  776. // T2F_C3F_V3F
  777. // T2F_N3F_V3F
  778. // T2F_C3F_N3F_V3F (non 1.1 format)
  779. // T2F_C4F_N3F_V3F
  780. //
  781. // There are no special cases for the following 1.1 formats:
  782. //
  783. // C4UB_V2F
  784. // C4UB_V3F
  785. // T4F_V4F
  786. // T2F_C4UB_V3F
  787. // T4F_C4F_N3F_V4F
  788. void FASTCALL VA_ValidateArrayPointers(__GLcontext *gc)
  789. {
  790. GLuint vaMask;
  791. GLuint formatMask;
  792. PFNVAELEMENT fp;
  793. PFNVAELEMENTBATCH fpB;
  794. PFNVAELEMENTBATCHINDIRECT fpBI;
  795. fp = VA_ArrayElement;
  796. fpB = VA_ArrayElementB;
  797. fpBI = VA_ArrayElementBI;
  798. vaMask = gc->vertexArray.mask;
  799. // The fast routines are for RGBA mode only. Edge flag and index array
  800. // pointers are disabled in these routines. Vertex array pointer is enabled.
  801. if (!gc->modes.colorIndexMode &&
  802. !(vaMask & (VAMASK_EDGEFLAG_ENABLE_MASK | VAMASK_INDEX_ENABLE_MASK)) &&
  803. (vaMask & VAMASK_VERTEX_ENABLE_MASK))
  804. {
  805. formatMask = VAMASK_VERTEX_TYPE_SIZE_MASK | VAMASK_VERTEX_ENABLE_MASK;
  806. if (vaMask & VAMASK_TEXCOORD_ENABLE_MASK)
  807. formatMask |= VAMASK_TEXCOORD_TYPE_SIZE_MASK | VAMASK_TEXCOORD_ENABLE_MASK;
  808. if (vaMask & VAMASK_COLOR_ENABLE_MASK)
  809. formatMask |= VAMASK_COLOR_TYPE_SIZE_MASK | VAMASK_COLOR_ENABLE_MASK;
  810. if (vaMask & VAMASK_NORMAL_ENABLE_MASK)
  811. formatMask |= VAMASK_NORMAL_TYPE_SIZE_MASK | VAMASK_NORMAL_ENABLE_MASK;
  812. switch (vaMask & formatMask)
  813. {
  814. case VAMASK_FORMAT_V2F:
  815. fp = VA_ArrayElement_V2F;
  816. fpB = VA_ArrayElement_V2F_B;
  817. fpBI = VA_ArrayElement_V2F_BI;
  818. break;
  819. case VAMASK_FORMAT_V3F:
  820. fp = VA_ArrayElement_V3F;
  821. fpB = VA_ArrayElement_V3F_B;
  822. fpBI = VA_ArrayElement_V3F_BI;
  823. break;
  824. case VAMASK_FORMAT_C3F_V3F:
  825. fp = VA_ArrayElement_C3F_V3F;
  826. fpB = VA_ArrayElement_C3F_V3F_B;
  827. fpBI = VA_ArrayElement_C3F_V3F_BI;
  828. break;
  829. case VAMASK_FORMAT_N3F_V3F:
  830. fp = VA_ArrayElement_N3F_V3F;
  831. fpB = VA_ArrayElement_N3F_V3F_B;
  832. fpBI = VA_ArrayElement_N3F_V3F_BI;
  833. break;
  834. case VAMASK_FORMAT_C3F_N3F_V3F:
  835. fp = VA_ArrayElement_C3F_N3F_V3F;
  836. fpB = VA_ArrayElement_C3F_N3F_V3F_B;
  837. fpBI = VA_ArrayElement_C3F_N3F_V3F_BI;
  838. break;
  839. case VAMASK_FORMAT_C4F_N3F_V3F:
  840. fp = VA_ArrayElement_C4F_N3F_V3F;
  841. fpB = VA_ArrayElement_C4F_N3F_V3F_B;
  842. fpBI = VA_ArrayElement_C4F_N3F_V3F_BI;
  843. break;
  844. case VAMASK_FORMAT_T2F_V3F:
  845. fp = VA_ArrayElement_T2F_V3F;
  846. fpB = VA_ArrayElement_T2F_V3F_B;
  847. fpBI = VA_ArrayElement_T2F_V3F_BI;
  848. break;
  849. case VAMASK_FORMAT_T2F_C3F_V3F:
  850. fp = VA_ArrayElement_T2F_C3F_V3F;
  851. fpB = VA_ArrayElement_T2F_C3F_V3F_B;
  852. fpBI = VA_ArrayElement_T2F_C3F_V3F_BI;
  853. break;
  854. case VAMASK_FORMAT_T2F_N3F_V3F:
  855. fp = VA_ArrayElement_T2F_N3F_V3F;
  856. fpB = VA_ArrayElement_T2F_N3F_V3F_B;
  857. fpBI = VA_ArrayElement_T2F_N3F_V3F_BI;
  858. break;
  859. case VAMASK_FORMAT_T2F_C3F_N3F_V3F:
  860. fp = VA_ArrayElement_T2F_C3F_N3F_V3F;
  861. fpB = VA_ArrayElement_T2F_C3F_N3F_V3F_B;
  862. fpBI = VA_ArrayElement_T2F_C3F_N3F_V3F_BI;
  863. break;
  864. case VAMASK_FORMAT_T2F_C4F_N3F_V3F:
  865. fp = VA_ArrayElement_T2F_C4F_N3F_V3F;
  866. fpB = VA_ArrayElement_T2F_C4F_N3F_V3F_B;
  867. fpBI = VA_ArrayElement_T2F_C4F_N3F_V3F_BI;
  868. break;
  869. }
  870. }
  871. // The default function pointers are used outside Begin.
  872. ASSERTOPENGL(gc->vertexArray.edgeFlag.pfn == (PFNGLVECTOR) glcltEdgeFlagv &&
  873. gc->vertexArray.edgeFlag.pfnCompile == (PFNGLVECTOR) __gllc_EdgeFlagv,
  874. "edgeFlag.pfn and edgeFlag.pfnCompile not initialized\n");
  875. gc->vertexArray.texCoord.pfn
  876. = afnTexCoord[(vaMask & VAMASK_TEXCOORD_TYPE_SIZE_MASK) >> VAMASK_TEXCOORD_TYPE_SHIFT];
  877. gc->vertexArray.texCoord.pfnCompile
  878. = afnTexCoordCompile[(vaMask & VAMASK_TEXCOORD_TYPE_SIZE_MASK) >> VAMASK_TEXCOORD_TYPE_SHIFT];
  879. if (gc->modes.colorIndexMode)
  880. {
  881. gc->vertexArray.color.pfn
  882. = afnColor_InCI[(vaMask & VAMASK_COLOR_TYPE_SIZE_MASK) >> VAMASK_COLOR_TYPE_SHIFT];
  883. gc->vertexArray.index.pfn
  884. = afnIndex_InCI[(vaMask & VAMASK_INDEX_TYPE_SIZE_MASK) >> VAMASK_INDEX_TYPE_SHIFT];
  885. }
  886. else
  887. {
  888. gc->vertexArray.color.pfn
  889. = afnColor_InRGBA[(vaMask & VAMASK_COLOR_TYPE_SIZE_MASK) >> VAMASK_COLOR_TYPE_SHIFT];
  890. gc->vertexArray.index.pfn
  891. = afnIndex_InRGBA[(vaMask & VAMASK_INDEX_TYPE_SIZE_MASK) >> VAMASK_INDEX_TYPE_SHIFT];
  892. }
  893. gc->vertexArray.color.pfnCompile
  894. = afnColorCompile[(vaMask & VAMASK_COLOR_TYPE_SIZE_MASK) >> VAMASK_COLOR_TYPE_SHIFT];
  895. gc->vertexArray.index.pfnCompile
  896. = afnIndexCompile[(vaMask & VAMASK_INDEX_TYPE_SIZE_MASK) >> VAMASK_INDEX_TYPE_SHIFT];
  897. gc->vertexArray.normal.pfn
  898. = afnNormal[(vaMask & VAMASK_NORMAL_TYPE_SIZE_MASK) >> VAMASK_NORMAL_TYPE_SHIFT];
  899. gc->vertexArray.normal.pfnCompile
  900. = afnNormalCompile[(vaMask & VAMASK_NORMAL_TYPE_SIZE_MASK) >> VAMASK_NORMAL_TYPE_SHIFT];
  901. gc->vertexArray.vertex.pfn
  902. = afnVertex[(vaMask & VAMASK_VERTEX_TYPE_SIZE_MASK) >> VAMASK_VERTEX_TYPE_SHIFT];
  903. gc->vertexArray.vertex.pfnCompile
  904. = afnVertexCompile[(vaMask & VAMASK_VERTEX_TYPE_SIZE_MASK) >> VAMASK_VERTEX_TYPE_SHIFT];
  905. gc->vertexArray.pfnArrayElement = fp;
  906. gc->vertexArray.pfnArrayElementBatch = fpB;
  907. gc->vertexArray.pfnArrayElementBatchIndirect = fpBI;
  908. gc->vertexArray.flags &= ~__GL_VERTEX_ARRAY_DIRTY;
  909. }
  910. void APIENTRY glcltArrayElement (GLint i)
  911. {
  912. __GL_SETUP();
  913. if (gc->vertexArray.flags & __GL_VERTEX_ARRAY_DIRTY)
  914. VA_ValidateArrayPointers(gc);
  915. // The fast routines are called in Begin only.
  916. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  917. (*gc->vertexArray.pfnArrayElement)(gc, i);
  918. else
  919. VA_ArrayElement(gc, i);
  920. }
  921. // Define fast VA_ArrayElement functions.
  922. #define __VA_ARRAY_ELEMENT_V2F 1
  923. #include "array.h"
  924. #undef __VA_ARRAY_ELEMENT_V2F
  925. #define __VA_ARRAY_ELEMENT_V3F 1
  926. #include "array.h"
  927. #undef __VA_ARRAY_ELEMENT_V3F
  928. #define __VA_ARRAY_ELEMENT_C3F_V3F 1
  929. #include "array.h"
  930. #undef __VA_ARRAY_ELEMENT_C3F_V3F
  931. #define __VA_ARRAY_ELEMENT_N3F_V3F 1
  932. #include "array.h"
  933. #undef __VA_ARRAY_ELEMENT_N3F_V3F
  934. #define __VA_ARRAY_ELEMENT_C3F_N3F_V3F 1
  935. #include "array.h"
  936. #undef __VA_ARRAY_ELEMENT_C3F_N3F_V3F
  937. #define __VA_ARRAY_ELEMENT_C4F_N3F_V3F 1
  938. #include "array.h"
  939. #undef __VA_ARRAY_ELEMENT_C4F_N3F_V3F
  940. #define __VA_ARRAY_ELEMENT_T2F_V3F 1
  941. #include "array.h"
  942. #undef __VA_ARRAY_ELEMENT_T2F_V3F
  943. #define __VA_ARRAY_ELEMENT_T2F_C3F_V3F 1
  944. #include "array.h"
  945. #undef __VA_ARRAY_ELEMENT_T2F_C3F_V3F
  946. #define __VA_ARRAY_ELEMENT_T2F_N3F_V3F 1
  947. #include "array.h"
  948. #undef __VA_ARRAY_ELEMENT_T2F_N3F_V3F
  949. #define __VA_ARRAY_ELEMENT_T2F_C3F_N3F_V3F 1
  950. #include "array.h"
  951. #undef __VA_ARRAY_ELEMENT_T2F_C3F_N3F_V3F
  952. #define __VA_ARRAY_ELEMENT_T2F_C4F_N3F_V3F 1
  953. #include "array.h"
  954. #undef __VA_ARRAY_ELEMENT_T2F_C4F_N3F_V3F
  955. #define CALLARRAYPOINTER(ap, i) \
  956. ((*(ap).pfn)((ap).pointer + (i) * (ap).ibytes))
  957. #define CALLARRAYPOINTERS \
  958. if (vaMask & VAMASK_EDGEFLAG_ENABLE_MASK) \
  959. CALLARRAYPOINTER(gc->vertexArray.edgeFlag, i); \
  960. if (vaMask & VAMASK_TEXCOORD_ENABLE_MASK) \
  961. CALLARRAYPOINTER(gc->vertexArray.texCoord, i); \
  962. if (vaMask & VAMASK_COLOR_ENABLE_MASK) \
  963. CALLARRAYPOINTER(gc->vertexArray.color, i); \
  964. if (vaMask & VAMASK_INDEX_ENABLE_MASK) \
  965. CALLARRAYPOINTER(gc->vertexArray.index, i); \
  966. if (vaMask & VAMASK_NORMAL_ENABLE_MASK) \
  967. CALLARRAYPOINTER(gc->vertexArray.normal, i); \
  968. if (vaMask & VAMASK_VERTEX_ENABLE_MASK) \
  969. CALLARRAYPOINTER(gc->vertexArray.vertex, i);
  970. void FASTCALL VA_ArrayElementB(__GLcontext *gc, GLint firstVertex, GLint nVertices)
  971. {
  972. GLint k, i;
  973. GLuint vaMask = gc->vertexArray.mask;
  974. for (k=0; k < nVertices; k++)
  975. {
  976. i = k+firstVertex;
  977. CALLARRAYPOINTERS;
  978. }
  979. }
  980. void FASTCALL VA_ArrayElementBI(__GLcontext *gc, GLint nVertices, VAMAP* indices)
  981. {
  982. GLint k, i;
  983. GLuint vaMask = gc->vertexArray.mask;
  984. for (k=0; k < nVertices; k++)
  985. {
  986. i = indices[k].iIn;
  987. CALLARRAYPOINTERS;
  988. }
  989. }
  990. void FASTCALL VA_ArrayElement(__GLcontext *gc, GLint i)
  991. {
  992. GLuint vaMask = gc->vertexArray.mask;
  993. CALLARRAYPOINTERS;
  994. }
  995. void APIENTRY glcltDrawArrays (GLenum mode, GLint first, GLsizei count)
  996. {
  997. int i;
  998. POLYARRAY *pa;
  999. PFNVAELEMENTBATCH pfn;
  1000. __GL_SETUP();
  1001. pa = gc->paTeb;
  1002. // Not allowed in begin/end.
  1003. if (pa->flags & POLYARRAY_IN_BEGIN)
  1004. {
  1005. GLSETERROR(GL_INVALID_OPERATION);
  1006. return;
  1007. }
  1008. if ((GLuint) mode > GL_POLYGON)
  1009. {
  1010. GLSETERROR(GL_INVALID_ENUM);
  1011. return;
  1012. }
  1013. if (count < 0)
  1014. {
  1015. GLSETERROR(GL_INVALID_VALUE);
  1016. return;
  1017. } else if (!count)
  1018. return;
  1019. // Find array element function to use.
  1020. if (gc->vertexArray.flags & __GL_VERTEX_ARRAY_DIRTY)
  1021. VA_ValidateArrayPointers(gc);
  1022. pfn = gc->vertexArray.pfnArrayElementBatch;
  1023. // Check polyarray buffer size before calling Begin.
  1024. // We will minimize breaking poly data records into batches where possible.
  1025. // The number 8 is loosely chosen to allow for the poly array entry
  1026. // and the flush limit. At worst, it causes an unnecessary attention!
  1027. if (count <= (GLsizei) gc->vertex.pdBufSize - 8 &&
  1028. count >= (GLsizei) (pa->pdBufferMax - pa->pdBufferNext + 1 - 8))
  1029. glsbAttention();
  1030. // Draw the array elements.
  1031. glcltBegin(mode);
  1032. pa->flags |= POLYARRAY_SAME_POLYDATA_TYPE;
  1033. (*pfn)(gc, first, count);
  1034. glcltEnd();
  1035. }
  1036. // Do not modify these constants. The code will likely break if they are
  1037. // changed.
  1038. #define VA_HASH_SIZE 256
  1039. #define VA_HASH(indexIn) ((GLubyte) indexIn)
  1040. // If the size of the mapping array is greater than 256, we need to change
  1041. // datatype and code below.
  1042. #if (VA_DRAWELEM_MAP_SIZE > 256)
  1043. #error "VA_DRAWELEM_MAP_SIZE is too large"
  1044. #endif
  1045. /******************************Public*Routine******************************\
  1046. * ReduceDrawElements
  1047. *
  1048. * Takes a set of DrawElements indices and reduces it into small chunks
  1049. * of unique vertex indices
  1050. *
  1051. * History:
  1052. * Sat Mar 02 14:25:26 1996 -by- Hock San Lee [hockl]
  1053. * Wrote original version embedded in DrawElements
  1054. * Sat Mar 02 14:25:26 1996 -by- Drew Bliss [drewb]
  1055. * Split into function shared between immediate and dlist
  1056. *
  1057. \**************************************************************************/
  1058. void FASTCALL ReduceDrawElements(__GLcontext *gc,
  1059. GLenum mode, GLsizei count, GLenum type,
  1060. const GLvoid *pIn,
  1061. pfnReducedElementsHandler pfnHandler)
  1062. {
  1063. GLushort _aHash[VA_HASH_SIZE + 2];
  1064. GLushort *pHash;
  1065. VAMAP aMap[VA_DRAWELEM_MAP_SIZE];
  1066. GLushort iMap, iMapNext;
  1067. GLushort iOutNext;
  1068. GLubyte aOut[VA_DRAWELEM_INDEX_SIZE];
  1069. GLsizei iPartialIndices;
  1070. GLsizei iCount, nLeft;
  1071. GLuint iIn;
  1072. // We will now sort the input index array using a hash table. The output
  1073. // index array will be zero based. For example, if the input array is
  1074. // [103, 101, 0, 2, 105, 103, 2, 4], the output index will be
  1075. // [0, 1, 2, 3, 4, 0, 3, 5]. This allows us to store
  1076. // vertices in a consecutive order.
  1077. // Dword aligned hash array.
  1078. pHash = (GLushort *) (((UINT_PTR) _aHash + 3) & ~3);
  1079. // Initialize input index array pointer.
  1080. iCount = 0;
  1081. iPartialIndices = 0;
  1082. DrawElements_NextBatch:
  1083. // Reset output index array for this batch.
  1084. // Initialize identity mapping for the first reserved vertex entries.
  1085. // New vertices are accumulated after them.
  1086. for (iOutNext = 0; iOutNext < (GLushort) iPartialIndices; iOutNext++)
  1087. aOut[iOutNext] = (GLubyte) iOutNext;
  1088. // Reset index mapping array that maps the In array to Out array.
  1089. // The index map corresponds to the vertices in the vertex buffer.
  1090. // Skip the reserved indices that are used for connectivity between
  1091. // partial primitives.
  1092. iMapNext = iOutNext;
  1093. // Reset hash array to no mapping (-1).
  1094. RtlFillMemoryUlong((PVOID) pHash, (ULONG) VA_HASH_SIZE * sizeof(*pHash),
  1095. (ULONG) -1);
  1096. // There are 3 possibilities in the following loop:
  1097. //
  1098. // 1. All input indices have been processed. The primitive is complete!
  1099. // 2. The index map overflows. We have accumulated 256 vertices for a partial
  1100. // primitive.
  1101. // 3. The output index array overflows. We have exceeded our estimated size
  1102. // of the output index array for a partial primitive.
  1103. for ( ; iCount < count; iCount++)
  1104. {
  1105. // Get next input index.
  1106. if (type == GL_UNSIGNED_BYTE)
  1107. iIn = (GLuint) ((GLubyte *) pIn)[iCount];
  1108. else if (type == GL_UNSIGNED_SHORT)
  1109. iIn = (GLuint) ((GLushort *) pIn)[iCount];
  1110. else
  1111. iIn = (GLuint) ((GLuint *) pIn)[iCount];
  1112. #if DRAWELEM_DEBUG
  1113. DbgPrint("iCount %d ", iCount);
  1114. DbgPrint("iIn %d ", iIn);
  1115. DbgPrint("iMapNext %d iOutNext %d",
  1116. (GLuint) iMapNext, (GLuint) iOutNext);
  1117. #endif
  1118. // Look up previously mapped index if one exists.
  1119. iMap = pHash[VA_HASH(iIn)];
  1120. while (iMap != (GLushort) -1 && aMap[iMap].iIn != iIn)
  1121. iMap = aMap[iMap].next;
  1122. #if DRAWELEM_DEBUG
  1123. DbgPrint("iMapFound %d\n", (GLuint) iMap);
  1124. #endif
  1125. // If aMap or aOut overflows, flush the partial primitive.
  1126. if (iOutNext >= VA_DRAWELEM_INDEX_SIZE ||
  1127. (iMap == (GLushort) -1 && iMapNext >= VA_DRAWELEM_MAP_SIZE))
  1128. {
  1129. #if DRAWELEM_DEBUG
  1130. DbgPrint("Flush iMapNext %d iOutNext %d\n",
  1131. (GLuint) iMapNext, (GLuint) iOutNext);
  1132. #endif
  1133. // We have accumulated enough vertices for a partial primitive. We now
  1134. // need to figure out the exact number of vertices to flush and redo
  1135. // the leftover vertices in the next partial primitive.
  1136. #if DBG
  1137. if (iOutNext >= VA_DRAWELEM_INDEX_SIZE)
  1138. DbgPrint("DrawElements: aOut buffer overflows\n");
  1139. #endif
  1140. // Find the flush vertex of this partial primitive.
  1141. nLeft = 0;
  1142. switch (mode)
  1143. {
  1144. case GL_LINE_STRIP:
  1145. case GL_TRIANGLE_FAN:
  1146. break;
  1147. case GL_POINTS:
  1148. case GL_LINE_LOOP:
  1149. case GL_POLYGON:
  1150. ASSERTOPENGL(FALSE, "unexpected primitive type\n");
  1151. break;
  1152. case GL_LINES:
  1153. case GL_TRIANGLE_STRIP:
  1154. case GL_QUAD_STRIP:
  1155. // number of vertices must be a multiple of 2
  1156. if (iOutNext % 2)
  1157. nLeft++;
  1158. break;
  1159. case GL_TRIANGLES:
  1160. // number of vertices must be a multiple of 3
  1161. switch (iOutNext % 3)
  1162. {
  1163. case 2: nLeft++; // fall through
  1164. case 1: nLeft++;
  1165. }
  1166. break;
  1167. case GL_QUADS:
  1168. // number of vertices must be a multiple of 4
  1169. switch (iOutNext % 4)
  1170. {
  1171. case 3: nLeft++; // fall through
  1172. case 2: nLeft++; // fall through
  1173. case 1: nLeft++;
  1174. }
  1175. break;
  1176. }
  1177. // Add the leftover vertices back to the input array and redo them
  1178. // in the next partial primitive.
  1179. iCount -= nLeft;
  1180. iOutNext -= (GLushort) nLeft;
  1181. // When passing on our data, skip any vertices
  1182. // that were reserved from a previous partial primitive
  1183. (*pfnHandler)(gc, mode,
  1184. iMapNext-iPartialIndices, 0, aMap+iPartialIndices,
  1185. iOutNext, aOut, GL_TRUE);
  1186. iPartialIndices = nReservedIndicesPartialBegin[mode];
  1187. // Continue to process remaining vertices.
  1188. goto DrawElements_NextBatch;
  1189. }
  1190. // If no previously mapped index is found, add the new vertex.
  1191. if (iMap == (GLushort) -1)
  1192. {
  1193. ASSERTOPENGL(iMapNext < VA_DRAWELEM_MAP_SIZE,
  1194. "index map overflows!\n");
  1195. #if DRAWELEM_DEBUG
  1196. DbgPrint(" Add iIn %d iMap %d iHash %d\n",
  1197. iIn, (GLuint) iMapNext, (GLuint) VA_HASH(iIn));
  1198. #endif
  1199. iMap = iMapNext++;
  1200. aMap[iMap].iIn = iIn;
  1201. aMap[iMap].next = pHash[VA_HASH(iIn)];
  1202. pHash[VA_HASH(iIn)] = iMap;
  1203. }
  1204. // Add the mapped index to output index array.
  1205. ASSERTOPENGL(iMap < VA_DRAWELEM_MAP_SIZE, "bad mapped index\n");
  1206. ASSERTOPENGL(iOutNext < VA_DRAWELEM_INDEX_SIZE,
  1207. "aOut array overflows!\n");
  1208. #if DRAWELEM_DEBUG
  1209. DbgPrint(" Add iOutNext %d iMap %d\n",
  1210. (GLuint) iOutNext, (GLuint) iMap);
  1211. #endif
  1212. aOut[iOutNext++] = (GLubyte) iMap;
  1213. }
  1214. // We have processed all input vertices.
  1215. // Pass on any remaining data
  1216. (*pfnHandler)(gc, mode,
  1217. iMapNext-iPartialIndices, 0, aMap+iPartialIndices,
  1218. iOutNext, aOut, GL_FALSE);
  1219. }
  1220. void FASTCALL glcltReducedElementsHandler(__GLcontext *gc,
  1221. GLenum mode,
  1222. GLsizei iVertexCount,
  1223. GLsizei iVertexBase,
  1224. VAMAP *pvmVertices,
  1225. GLsizei iElementCount,
  1226. GLubyte *pbElements,
  1227. GLboolean fPartial)
  1228. {
  1229. POLYARRAY *pa = gc->paTeb;
  1230. PFNVAELEMENT pfn;
  1231. GLsizei i;
  1232. // Set up the vertex data
  1233. pfn = gc->vertexArray.pfnArrayElement;
  1234. if (pvmVertices != NULL)
  1235. {
  1236. PFNVAELEMENTBATCHINDIRECT pfn = gc->vertexArray.pfnArrayElementBatchIndirect;
  1237. (*pfn)(gc, iVertexCount, pvmVertices);
  1238. }
  1239. else
  1240. {
  1241. // Access consecutive block of vertices, starting at iVertexBase
  1242. PFNVAELEMENTBATCH pfn = gc->vertexArray.pfnArrayElementBatch;
  1243. (*pfn)(gc, iVertexBase, iVertexCount);
  1244. }
  1245. // Copy the index array to the end of the polyarray primitive.
  1246. pa->nIndices = (GLuint) iElementCount;
  1247. // skip terminator vertex
  1248. pa->aIndices = (GLubyte *) (pa->pdNextVertex + 1);
  1249. ASSERTOPENGL(pa->aIndices + pa->nIndices
  1250. <= (GLubyte *) (pa->pdBufferMax+1),
  1251. "Vertex buffer overflows!\n");
  1252. memcpy(pa->aIndices, pbElements, pa->nIndices * sizeof(GLubyte));
  1253. if (fPartial)
  1254. {
  1255. // Flush the partial primitive.
  1256. VA_DrawElementsFlushPartialPrimitive(pa, mode);
  1257. }
  1258. else
  1259. {
  1260. VA_DrawElementsEnd(pa);
  1261. }
  1262. }
  1263. // This handles primitive modes that DrawElements or DrawRangeElements don't.
  1264. void FASTCALL VA_DrawElementsHandleOtherPrimTypes( __GLcontext *gc,
  1265. GLenum mode,
  1266. GLsizei count,
  1267. GLenum type,
  1268. GLvoid *pIn )
  1269. {
  1270. GLsizei iCount;
  1271. PFNVAELEMENT pfn;
  1272. POLYARRAY *pa;
  1273. GLuint iIn;
  1274. pa = gc->paTeb;
  1275. pfn = gc->vertexArray.pfnArrayElement;
  1276. glcltBegin(mode);
  1277. pa->flags |= POLYARRAY_SAME_POLYDATA_TYPE;
  1278. for (iCount = 0; iCount < count; iCount++)
  1279. {
  1280. // Get next input index.
  1281. if (type == GL_UNSIGNED_BYTE)
  1282. iIn = (GLuint) ((GLubyte *) pIn)[iCount];
  1283. else if (type == GL_UNSIGNED_SHORT)
  1284. iIn = (GLuint) ((GLushort *) pIn)[iCount];
  1285. else
  1286. iIn = (GLuint) ((GLuint *) pIn)[iCount];
  1287. (*pfn)(gc, iIn);
  1288. }
  1289. glcltEnd();
  1290. }
  1291. void APIENTRY glcltDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *pIn)
  1292. {
  1293. POLYARRAY *pa;
  1294. GLuint iIn;
  1295. GLsizei iCount;
  1296. __GL_SETUP();
  1297. pa = gc->paTeb;
  1298. #define DRAWELEM_DEBUG 0
  1299. #if DRAWELEM_DEBUG
  1300. {
  1301. DbgPrint("mode %d, count %d, type %d\n", mode, count, type);
  1302. DbgPrint("pIn: ");
  1303. for (iCount = 0; iCount < count; iCount++)
  1304. {
  1305. if (type == GL_UNSIGNED_BYTE)
  1306. iIn = (GLuint) ((GLubyte *) pIn)[iCount];
  1307. else if (type == GL_UNSIGNED_SHORT)
  1308. iIn = (GLuint) ((GLushort *) pIn)[iCount];
  1309. else
  1310. iIn = (GLuint) ((GLuint *) pIn)[iCount];
  1311. DbgPrint("%d ", iIn);
  1312. }
  1313. DbgPrint("\n");
  1314. }
  1315. #endif
  1316. // If we are already in the begin/end bracket, return an error.
  1317. if (pa->flags & POLYARRAY_IN_BEGIN)
  1318. {
  1319. GLSETERROR(GL_INVALID_OPERATION);
  1320. return;
  1321. }
  1322. if ((GLuint) mode > GL_POLYGON)
  1323. {
  1324. GLSETERROR(GL_INVALID_ENUM);
  1325. return;
  1326. }
  1327. if (count < 0)
  1328. {
  1329. GLSETERROR(GL_INVALID_VALUE);
  1330. return;
  1331. } else if (!count)
  1332. return;
  1333. switch (type)
  1334. {
  1335. case GL_UNSIGNED_BYTE:
  1336. case GL_UNSIGNED_SHORT:
  1337. case GL_UNSIGNED_INT:
  1338. break;
  1339. default:
  1340. GLSETERROR(GL_INVALID_ENUM);
  1341. return;
  1342. }
  1343. // Find array element function to use.
  1344. if (gc->vertexArray.flags & __GL_VERTEX_ARRAY_DIRTY)
  1345. VA_ValidateArrayPointers(gc);
  1346. // Send Points, Line Loop, and Polygon to Begin/End call. Points and Polygon
  1347. // don't benefit from optimization in this function. Further, Polygon and
  1348. // Line Loop are too tricky to deal with in this function.
  1349. if (mode == GL_POINTS || mode == GL_LINE_LOOP || mode == GL_POLYGON)
  1350. {
  1351. VA_DrawElementsHandleOtherPrimTypes( gc, mode, count, type, (GLvoid *) pIn );
  1352. return;
  1353. }
  1354. // Begin primitive.
  1355. VA_DrawElementsBegin(pa, mode, count);
  1356. // The primitive will be ended on the last batch of
  1357. // elements
  1358. ReduceDrawElements(gc, mode, count, type, pIn,
  1359. glcltReducedElementsHandler);
  1360. }
  1361. void RebaseIndices( GLvoid *pIn, GLubyte *aOut, GLsizei count, GLuint start,
  1362. GLenum type )
  1363. {
  1364. if (type == GL_UNSIGNED_BYTE) {
  1365. while( count-- )
  1366. *aOut++ = (GLubyte) ( ((GLuint) *( ((GLubyte *) pIn) ++ )) - start);
  1367. }
  1368. else if (type == GL_UNSIGNED_SHORT) {
  1369. while( count-- )
  1370. *aOut++ = (GLubyte) ( ((GLuint) *( ((GLushort *) pIn) ++ )) - start);
  1371. }
  1372. else {
  1373. while( count-- )
  1374. *aOut++ = (GLubyte) ( ((GLuint) *( ((GLuint *) pIn) ++ )) - start);
  1375. }
  1376. }
  1377. void APIENTRY glcltDrawRangeElementsWIN(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *pIn)
  1378. {
  1379. POLYARRAY *pa;
  1380. GLuint iVertexCount;
  1381. GLubyte aOut[VA_DRAWELEM_INDEX_SIZE];
  1382. __GL_SETUP();
  1383. pa = gc->paTeb;
  1384. // If we are already in the begin/end bracket, return an error.
  1385. if (pa->flags & POLYARRAY_IN_BEGIN)
  1386. {
  1387. GLSETERROR(GL_INVALID_OPERATION);
  1388. return;
  1389. }
  1390. if ((GLuint) mode > GL_POLYGON)
  1391. {
  1392. GLSETERROR(GL_INVALID_ENUM);
  1393. return;
  1394. }
  1395. iVertexCount = end-start+1;
  1396. if( (count < 0) ||
  1397. (end < start) )
  1398. {
  1399. GLSETERROR(GL_INVALID_VALUE);
  1400. return;
  1401. }
  1402. else if (!count)
  1403. {
  1404. return;
  1405. }
  1406. switch (type)
  1407. {
  1408. case GL_UNSIGNED_BYTE:
  1409. case GL_UNSIGNED_SHORT:
  1410. case GL_UNSIGNED_INT:
  1411. break;
  1412. default:
  1413. GLSETERROR(GL_INVALID_ENUM);
  1414. return;
  1415. }
  1416. if (gc->vertexArray.flags & __GL_VERTEX_ARRAY_DIRTY)
  1417. VA_ValidateArrayPointers(gc);
  1418. // Send Points, Line Loop, and Polygon to Begin/End call. Points and Polygon
  1419. // don't benefit from optimization in this function. Further, Polygon and
  1420. // Line Loop are too tricky to deal with in this function.
  1421. if (mode == GL_POINTS || mode == GL_LINE_LOOP || mode == GL_POLYGON)
  1422. {
  1423. VA_DrawElementsHandleOtherPrimTypes( gc, mode, count, type, (GLvoid *) pIn );
  1424. return;
  1425. }
  1426. // Begin primitive.
  1427. VA_DrawElementsBegin(pa, mode, count);
  1428. if ( (count > VA_DRAWRANGEELEM_MAX_INDICES) ||
  1429. (iVertexCount > VA_DRAWRANGEELEM_MAX_VERTICES) )
  1430. {
  1431. // The primitive is too large to be processed directly so
  1432. // we have to reduce it. The primitive will be ended on the
  1433. // last batch of elements.
  1434. ReduceDrawElements(gc, mode, count, type, pIn,
  1435. glcltReducedElementsHandler);
  1436. }
  1437. else
  1438. {
  1439. // Need to rebase (0-base) the indices and convert them to ubyte for
  1440. // the reduced element handler.
  1441. RebaseIndices( (GLvoid *) pIn, aOut, count, start, type );
  1442. // Finish primitive
  1443. glcltReducedElementsHandler(gc, mode,
  1444. iVertexCount,
  1445. start, // iVertexBase
  1446. NULL,
  1447. count,
  1448. aOut,
  1449. GL_FALSE);
  1450. }
  1451. }
  1452. // Interleaved array AND mask.
  1453. // INTERLEAVED_FORMAT_ASSERT
  1454. GLuint iaAndMask[14] =
  1455. {
  1456. // GL_V2F
  1457. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1458. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1459. VAMASK_INDEX_TYPE_SIZE_MASK |
  1460. VAMASK_COLOR_TYPE_SIZE_MASK |
  1461. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1462. // GL_V3F
  1463. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1464. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1465. VAMASK_INDEX_TYPE_SIZE_MASK |
  1466. VAMASK_COLOR_TYPE_SIZE_MASK |
  1467. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1468. // GL_C4UB_V2F
  1469. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1470. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1471. VAMASK_INDEX_TYPE_SIZE_MASK |
  1472. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1473. // GL_C4UB_V3F
  1474. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1475. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1476. VAMASK_INDEX_TYPE_SIZE_MASK |
  1477. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1478. // GL_C3F_V3F
  1479. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1480. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1481. VAMASK_INDEX_TYPE_SIZE_MASK |
  1482. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1483. // GL_N3F_V3F
  1484. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1485. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1486. VAMASK_INDEX_TYPE_SIZE_MASK |
  1487. VAMASK_COLOR_TYPE_SIZE_MASK,
  1488. // GL_C4F_N3F_V3F
  1489. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1490. VAMASK_TEXCOORD_TYPE_SIZE_MASK |
  1491. VAMASK_INDEX_TYPE_SIZE_MASK,
  1492. // GL_T2F_V3F
  1493. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1494. VAMASK_INDEX_TYPE_SIZE_MASK |
  1495. VAMASK_COLOR_TYPE_SIZE_MASK |
  1496. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1497. // GL_T4F_V4F
  1498. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1499. VAMASK_INDEX_TYPE_SIZE_MASK |
  1500. VAMASK_COLOR_TYPE_SIZE_MASK |
  1501. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1502. // GL_T2F_C4UB_V3F
  1503. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1504. VAMASK_INDEX_TYPE_SIZE_MASK |
  1505. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1506. // GL_T2F_C3F_V3F
  1507. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1508. VAMASK_INDEX_TYPE_SIZE_MASK |
  1509. VAMASK_NORMAL_TYPE_SIZE_MASK,
  1510. // GL_T2F_N3F_V3F
  1511. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1512. VAMASK_INDEX_TYPE_SIZE_MASK |
  1513. VAMASK_COLOR_TYPE_SIZE_MASK,
  1514. // GL_T2F_C4F_N3F_V3F
  1515. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1516. VAMASK_INDEX_TYPE_SIZE_MASK,
  1517. // GL_T4F_C4F_N3F_V4F
  1518. VAMASK_EDGEFLAG_TYPE_SIZE_MASK |
  1519. VAMASK_INDEX_TYPE_SIZE_MASK,
  1520. };
  1521. // Interleaved array OR mask.
  1522. // INTERLEAVED_FORMAT_ASSERT
  1523. GLuint iaOrMask[14] =
  1524. {
  1525. VAMASK_FORMAT_V2F, // GL_V2F
  1526. VAMASK_FORMAT_V3F, // GL_V3F
  1527. VAMASK_FORMAT_C4UB_V2F, // GL_C4UB_V2F
  1528. VAMASK_FORMAT_C4UB_V3F, // GL_C4UB_V3F
  1529. VAMASK_FORMAT_C3F_V3F, // GL_C3F_V3F
  1530. VAMASK_FORMAT_N3F_V3F, // GL_N3F_V3F
  1531. VAMASK_FORMAT_C4F_N3F_V3F, // GL_C4F_N3F_V3F
  1532. VAMASK_FORMAT_T2F_V3F, // GL_T2F_V3F
  1533. VAMASK_FORMAT_T4F_V4F, // GL_T4F_V4F
  1534. VAMASK_FORMAT_T2F_C4UB_V3F, // GL_T2F_C4UB_V3F
  1535. VAMASK_FORMAT_T2F_C3F_V3F, // GL_T2F_C3F_V3F
  1536. VAMASK_FORMAT_T2F_N3F_V3F, // GL_T2F_N3F_V3F
  1537. VAMASK_FORMAT_T2F_C4F_N3F_V3F, // GL_T2F_C4F_N3F_V3F
  1538. VAMASK_FORMAT_T4F_C4F_N3F_V4F, // GL_T4F_C4F_N3F_V4F
  1539. };
  1540. // Interleaved array default strides.
  1541. GLuint iaStride[14] =
  1542. {
  1543. 2 * sizeof(GLfloat), // GL_V2F
  1544. 3 * sizeof(GLfloat), // GL_V3F
  1545. 2 * sizeof(GLfloat) + 4 * sizeof(GLubyte), // GL_C4UB_V2F
  1546. 3 * sizeof(GLfloat) + 4 * sizeof(GLubyte), // GL_C4UB_V3F
  1547. 6 * sizeof(GLfloat), // GL_C3F_V3F
  1548. 6 * sizeof(GLfloat), // GL_N3F_V3F
  1549. 10 * sizeof(GLfloat), // GL_C4F_N3F_V3F
  1550. 5 * sizeof(GLfloat), // GL_T2F_V3F
  1551. 8 * sizeof(GLfloat), // GL_T4F_V4F
  1552. 5 * sizeof(GLfloat) + 4 * sizeof(GLubyte), // GL_T2F_C4UB_V3F
  1553. 8 * sizeof(GLfloat), // GL_T2F_C3F_V3F
  1554. 8 * sizeof(GLfloat), // GL_T2F_N3F_V3F
  1555. 12 * sizeof(GLfloat), // GL_T2F_C4F_N3F_V3F
  1556. 15 * sizeof(GLfloat), // GL_T4F_C4F_N3F_V4F
  1557. };
  1558. void APIENTRY glcltInterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer)
  1559. {
  1560. GLuint iFormat, iStride;
  1561. GLuint vaMask;
  1562. const GLbyte *pb = pointer;
  1563. __GL_SETUP();
  1564. // Not allowed in begin/end.
  1565. if (gc->paTeb->flags & POLYARRAY_IN_BEGIN)
  1566. {
  1567. GLSETERROR(GL_INVALID_OPERATION);
  1568. return;
  1569. }
  1570. // INTERLEAVED_FORMAT_ASSERT
  1571. iFormat = (GLuint) (format - GL_V2F);
  1572. if (iFormat > GL_T4F_C4F_N3F_V4F)
  1573. {
  1574. GLSETERROR(GL_INVALID_ENUM);
  1575. return;
  1576. }
  1577. if (stride < 0)
  1578. {
  1579. GLSETERROR(GL_INVALID_VALUE);
  1580. return;
  1581. }
  1582. if (stride)
  1583. iStride = stride;
  1584. else
  1585. iStride = iaStride[iFormat];
  1586. // Compute new mask.
  1587. // If we are disabling an array, don't modify its type and size field!
  1588. vaMask = gc->vertexArray.mask;
  1589. vaMask &= iaAndMask[iFormat];
  1590. vaMask |= iaOrMask[iFormat];
  1591. if (gc->vertexArray.mask != vaMask)
  1592. {
  1593. gc->vertexArray.mask = vaMask;
  1594. gc->vertexArray.flags |= __GL_VERTEX_ARRAY_DIRTY;
  1595. }
  1596. if (vaMask & VAMASK_TEXCOORD_ENABLE_MASK)
  1597. {
  1598. gc->vertexArray.texCoord.type = GL_FLOAT;
  1599. gc->vertexArray.texCoord.stride = iStride;
  1600. gc->vertexArray.texCoord.ibytes = iStride;
  1601. gc->vertexArray.texCoord.pointer = pb;
  1602. if ((vaMask & VAMASK_TEXCOORD_TYPE_SIZE_MASK) ==
  1603. (VAMASK_TEXCOORD_SIZE_4 | VAMASK_TEXCOORD_TYPE_FLOAT))
  1604. {
  1605. gc->vertexArray.texCoord.size = 4;
  1606. pb += 4 * sizeof(GLfloat);
  1607. }
  1608. else
  1609. {
  1610. ASSERTOPENGL((vaMask & VAMASK_TEXCOORD_TYPE_SIZE_MASK) ==
  1611. (VAMASK_TEXCOORD_SIZE_2 | VAMASK_TEXCOORD_TYPE_FLOAT),
  1612. "unhandled texcoord format\n");
  1613. gc->vertexArray.texCoord.size = 2;
  1614. pb += 2 * sizeof(GLfloat);
  1615. }
  1616. }
  1617. if (vaMask & VAMASK_COLOR_ENABLE_MASK)
  1618. {
  1619. gc->vertexArray.color.stride = iStride;
  1620. gc->vertexArray.color.ibytes = iStride;
  1621. gc->vertexArray.color.pointer = pb;
  1622. switch (vaMask & VAMASK_COLOR_TYPE_SIZE_MASK)
  1623. {
  1624. case VAMASK_COLOR_TYPE_UBYTE | VAMASK_COLOR_SIZE_4:
  1625. gc->vertexArray.color.type = GL_UNSIGNED_BYTE;
  1626. gc->vertexArray.color.size = 4;
  1627. pb += 4 * sizeof(GLubyte);
  1628. break;
  1629. case VAMASK_COLOR_TYPE_FLOAT | VAMASK_COLOR_SIZE_3:
  1630. gc->vertexArray.color.type = GL_FLOAT;
  1631. gc->vertexArray.color.size = 3;
  1632. pb += 3 * sizeof(GLfloat);
  1633. break;
  1634. case VAMASK_COLOR_TYPE_FLOAT | VAMASK_COLOR_SIZE_4:
  1635. gc->vertexArray.color.type = GL_FLOAT;
  1636. gc->vertexArray.color.size = 4;
  1637. pb += 4 * sizeof(GLfloat);
  1638. break;
  1639. default:
  1640. ASSERTOPENGL(FALSE, "unhandled color format\n");
  1641. break;
  1642. }
  1643. }
  1644. if (vaMask & VAMASK_NORMAL_ENABLE_MASK)
  1645. {
  1646. gc->vertexArray.normal.type = GL_FLOAT;
  1647. gc->vertexArray.normal.stride = iStride;
  1648. gc->vertexArray.normal.ibytes = iStride;
  1649. gc->vertexArray.normal.pointer = pb;
  1650. pb += 3 * sizeof(GLfloat);
  1651. }
  1652. gc->vertexArray.vertex.type = GL_FLOAT;
  1653. gc->vertexArray.vertex.stride = iStride;
  1654. gc->vertexArray.vertex.ibytes = iStride;
  1655. gc->vertexArray.vertex.pointer = pb;
  1656. switch (vaMask & VAMASK_VERTEX_TYPE_SIZE_MASK)
  1657. {
  1658. case VAMASK_VERTEX_TYPE_FLOAT | VAMASK_VERTEX_SIZE_4:
  1659. gc->vertexArray.vertex.size = 4;
  1660. break;
  1661. case VAMASK_VERTEX_TYPE_FLOAT | VAMASK_VERTEX_SIZE_3:
  1662. gc->vertexArray.vertex.size = 3;
  1663. break;
  1664. case VAMASK_VERTEX_TYPE_FLOAT | VAMASK_VERTEX_SIZE_2:
  1665. gc->vertexArray.vertex.size = 2;
  1666. break;
  1667. default:
  1668. ASSERTOPENGL(FALSE, "unhandled vertex format\n");
  1669. break;
  1670. }
  1671. }