1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #include "QF/sys.h"
6
7 #include "QF/GL/defines.h"
8 #include "QF/GL/funcs.h"
9
10 typedef void (*qfgl_func_t) (const GLvoid *);
11
12 static const GLvoid *color_pointer;
13 static GLsizei color_stride;
14 static qfgl_func_t color_func;
15 static int color_enabled = 0;
16
17 static const GLvoid *edgeflag_pointer;
18 static GLsizei edgeflag_stride;
19 static int edgeflag_enabled = 0;
20
21 static const GLvoid *index_pointer;
22 static GLsizei index_stride;
23 static qfgl_func_t index_func;
24 static int index_enabled = 0;
25
26 static const GLvoid *normal_pointer;
27 static GLsizei normal_stride;
28 static qfgl_func_t normal_func;
29 static int normal_enabled = 0;
30
31 static const GLvoid *texcoord_pointer;
32 static GLsizei texcoord_stride;
33 static qfgl_func_t texcoord_func;
34 static int texcoord_enabled = 0;
35
36 static const GLvoid *vertex_pointer;
37 static GLsizei vertex_stride;
38 static qfgl_func_t vertex_func;
39 static int vertex_enabled = 0;
40
41 static qfgl_func_t *color_functions[][8] = {
42 {
43 (qfgl_func_t *) (char *) &qfglColor3bv,
44 (qfgl_func_t *) (char *) &qfglColor3ubv,
45 (qfgl_func_t *) (char *) &qfglColor3sv,
46 (qfgl_func_t *) (char *) &qfglColor3usv,
47 (qfgl_func_t *) (char *) &qfglColor3iv,
48 (qfgl_func_t *) (char *) &qfglColor3uiv,
49 (qfgl_func_t *) (char *) &qfglColor3fv,
50 (qfgl_func_t *) (char *) &qfglColor3dv,
51 },
52 {
53 (qfgl_func_t *) (char *) &qfglColor4bv,
54 (qfgl_func_t *) (char *) &qfglColor4ubv,
55 (qfgl_func_t *) (char *) &qfglColor4sv,
56 (qfgl_func_t *) (char *) &qfglColor4usv,
57 (qfgl_func_t *) (char *) &qfglColor4iv,
58 (qfgl_func_t *) (char *) &qfglColor4uiv,
59 (qfgl_func_t *) (char *) &qfglColor4fv,
60 (qfgl_func_t *) (char *) &qfglColor4dv,
61 },
62 };
63
64 static qfgl_func_t *index_functions[] = {
65 (qfgl_func_t *) (char *) &qfglIndexubv,
66 (qfgl_func_t *) (char *) &qfglIndexsv,
67 (qfgl_func_t *) (char *) &qfglIndexiv,
68 (qfgl_func_t *) (char *) &qfglIndexfv,
69 (qfgl_func_t *) (char *) &qfglIndexdv,
70 };
71
72 static qfgl_func_t *normal_functions[] = {
73 (qfgl_func_t *) (char *) &qfglNormal3bv,
74 (qfgl_func_t *) (char *) &qfglNormal3sv,
75 (qfgl_func_t *) (char *) &qfglNormal3iv,
76 (qfgl_func_t *) (char *) &qfglNormal3fv,
77 (qfgl_func_t *) (char *) &qfglNormal3dv,
78 };
79
80 static qfgl_func_t *texcoord_functions[][4] = {
81 {
82 (qfgl_func_t *) (char *) &qfglTexCoord1sv,
83 (qfgl_func_t *) (char *) &qfglTexCoord1iv,
84 (qfgl_func_t *) (char *) &qfglTexCoord1fv,
85 (qfgl_func_t *) (char *) &qfglTexCoord1dv,
86 },
87 {
88 (qfgl_func_t *) (char *) &qfglTexCoord2sv,
89 (qfgl_func_t *) (char *) &qfglTexCoord2iv,
90 (qfgl_func_t *) (char *) &qfglTexCoord2fv,
91 (qfgl_func_t *) (char *) &qfglTexCoord2dv,
92 },
93 {
94 (qfgl_func_t *) (char *) &qfglTexCoord3sv,
95 (qfgl_func_t *) (char *) &qfglTexCoord3iv,
96 (qfgl_func_t *) (char *) &qfglTexCoord3fv,
97 (qfgl_func_t *) (char *) &qfglTexCoord3dv,
98 },
99 {
100 (qfgl_func_t *) (char *) &qfglTexCoord4sv,
101 (qfgl_func_t *) (char *) &qfglTexCoord4iv,
102 (qfgl_func_t *) (char *) &qfglTexCoord4fv,
103 (qfgl_func_t *) (char *) &qfglTexCoord4dv,
104 },
105 };
106
107 static qfgl_func_t *vertex_functions[][4] = {
108 {
109 (qfgl_func_t *) (char *) &qfglVertex2sv,
110 (qfgl_func_t *) (char *) &qfglVertex2iv,
111 (qfgl_func_t *) (char *) &qfglVertex2fv,
112 (qfgl_func_t *) (char *) &qfglVertex2dv,
113 },
114 {
115 (qfgl_func_t *) (char *) &qfglVertex3sv,
116 (qfgl_func_t *) (char *) &qfglVertex3iv,
117 (qfgl_func_t *) (char *) &qfglVertex3fv,
118 (qfgl_func_t *) (char *) &qfglVertex3dv,
119 },
120 {
121 (qfgl_func_t *) (char *) &qfglVertex4sv,
122 (qfgl_func_t *) (char *) &qfglVertex4iv,
123 (qfgl_func_t *) (char *) &qfglVertex4fv,
124 (qfgl_func_t *) (char *) &qfglVertex4dv,
125 },
126 };
127
128 static void
qfgl_ColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)129 qfgl_ColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
130 {
131 int index;
132 int bytes = 0;
133
134 switch (type) {
135 case GL_BYTE:
136 index = 0;
137 bytes = sizeof (GLbyte);
138 break;
139 case GL_UNSIGNED_BYTE:
140 index = 1;
141 bytes = sizeof (GLubyte);
142 break;
143 case GL_SHORT:
144 index = 2;
145 bytes = sizeof (GLshort);
146 break;
147 case GL_UNSIGNED_SHORT:
148 index = 3;
149 bytes = sizeof (GLushort);
150 break;
151 case GL_INT:
152 index = 4;
153 bytes = sizeof (GLint);
154 break;
155 case GL_UNSIGNED_INT:
156 index = 5;
157 bytes = sizeof (GLuint);
158 break;
159 case GL_FLOAT:
160 index = 6;
161 bytes = sizeof (GLfloat);
162 break;
163 case GL_DOUBLE:
164 index = 7;
165 bytes = sizeof (GLdouble);
166 break;
167 default:
168 return;
169 }
170 color_pointer = ptr;
171 // color_stride = stride + size * bytes;
172 color_stride = stride ? stride : size * bytes;
173 color_func = *color_functions[size - 3][index];
174 }
175
176 static void
qfgl_EdgeFlagPointer(GLsizei stride,const GLvoid * ptr)177 qfgl_EdgeFlagPointer (GLsizei stride, const GLvoid *ptr)
178 {
179 edgeflag_pointer = ptr;
180 edgeflag_stride = stride + sizeof (GLboolean);
181 }
182
183 static void
qfgl_IndexPointer(GLenum type,GLsizei stride,const GLvoid * ptr)184 qfgl_IndexPointer (GLenum type, GLsizei stride, const GLvoid *ptr)
185 {
186 int index;
187 int bytes = 0;
188
189 switch (type) {
190 case GL_UNSIGNED_BYTE:
191 index = 0;
192 bytes = sizeof (GLubyte);
193 break;
194 case GL_SHORT:
195 index = 1;
196 bytes = sizeof (GLshort);
197 break;
198 case GL_INT:
199 index = 2;
200 bytes = sizeof (GLint);
201 break;
202 case GL_FLOAT:
203 index = 3;
204 bytes = sizeof (GLfloat);
205 break;
206 case GL_DOUBLE:
207 index = 4;
208 bytes = sizeof (GLdouble);
209 break;
210 default:
211 return;
212 }
213 index_pointer = ptr;
214 index_stride = stride + bytes;
215 index_func = *index_functions[index];
216 }
217
218 static void
qfgl_NormalPointer(GLenum type,GLsizei stride,const GLvoid * ptr)219 qfgl_NormalPointer (GLenum type, GLsizei stride, const GLvoid *ptr)
220 {
221 int index;
222 int bytes = 0;
223
224 switch (type) {
225 case GL_BYTE:
226 index = 0;
227 bytes = sizeof (GLbyte);
228 break;
229 case GL_SHORT:
230 index = 1;
231 bytes = sizeof (GLshort);
232 break;
233 case GL_INT:
234 index = 2;
235 bytes = sizeof (GLint);
236 break;
237 case GL_FLOAT:
238 index = 3;
239 bytes = sizeof (GLfloat);
240 break;
241 case GL_DOUBLE:
242 index = 4;
243 bytes = sizeof (GLdouble);
244 break;
245 default:
246 return;
247 }
248 normal_pointer = ptr;
249 normal_stride = stride + bytes;
250 normal_func = *normal_functions[index];
251 }
252
253 static void
qfgl_TexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)254 qfgl_TexCoordPointer (GLint size, GLenum type, GLsizei stride,
255 const GLvoid *ptr)
256 {
257 int index;
258 int bytes = 0;
259
260 switch (type) {
261 case GL_SHORT:
262 index = 0;
263 bytes = sizeof (GLshort);
264 break;
265 case GL_INT:
266 index = 1;
267 bytes = sizeof (GLint);
268 break;
269 case GL_FLOAT:
270 index = 2;
271 bytes = sizeof (GLfloat);
272 break;
273 case GL_DOUBLE:
274 index = 3;
275 bytes = sizeof (GLdouble);
276 break;
277 default:
278 return;
279 }
280 texcoord_pointer = ptr;
281 texcoord_stride = stride + size * bytes;
282 texcoord_func = *texcoord_functions[size - 1][index];
283 }
284
285 static void
qfgl_VertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)286 qfgl_VertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
287 {
288 int index;
289 int bytes = 0;
290
291 switch (type) {
292 case GL_SHORT:
293 index = 0;
294 bytes = sizeof (GLshort);
295 break;
296 case GL_INT:
297 index = 1;
298 bytes = sizeof (GLint);
299 break;
300 case GL_FLOAT:
301 index = 2;
302 bytes = sizeof (GLfloat);
303 break;
304 case GL_DOUBLE:
305 index = 3;
306 bytes = sizeof (GLdouble);
307 break;
308 default:
309 return;
310 }
311 vertex_pointer = ptr;
312 vertex_stride = stride + size * bytes;
313 vertex_func = *vertex_functions[size - 2][index];
314 }
315
316 static void
qfgl_InterleavedArrays(GLenum format,GLsizei stride,const GLvoid * pointer)317 qfgl_InterleavedArrays (GLenum format, GLsizei stride, const GLvoid *pointer)
318 {
319 const GLbyte *ptr = pointer;
320
321 switch (format) {
322 case GL_V2F:
323 stride += 2 * sizeof (GLfloat);
324 break;
325 case GL_V3F:
326 stride += 3 * sizeof (GLfloat);
327 break;
328 case GL_C4UB_V2F:
329 stride += 4 * sizeof (GLubyte);
330 stride += 2 * sizeof (GLfloat);
331 break;
332 case GL_C4UB_V3F:
333 stride += 4 * sizeof (GLubyte);
334 stride += 3 * sizeof (GLfloat);
335 break;
336 case GL_C3F_V3F:
337 stride += 3 * sizeof (GLfloat);
338 stride += 3 * sizeof (GLfloat);
339 break;
340 case GL_N3F_V3F:
341 stride += 3 * sizeof (GLfloat);
342 stride += 3 * sizeof (GLfloat);
343 break;
344 case GL_C4F_N3F_V3F:
345 stride += 4 * sizeof (GLfloat);
346 stride += 3 * sizeof (GLfloat);
347 stride += 3 * sizeof (GLfloat);
348 break;
349 case GL_T2F_V3F:
350 stride += 2 * sizeof (GLfloat);
351 stride += 3 * sizeof (GLfloat);
352 break;
353 case GL_T4F_V4F:
354 stride += 4 * sizeof (GLfloat);
355 stride += 4 * sizeof (GLfloat);
356 break;
357 case GL_T2F_C4UB_V3F:
358 stride += 2 * sizeof (GLfloat);
359 stride += 4 * sizeof (GLubyte);
360 stride += 3 * sizeof (GLfloat);
361 break;
362 case GL_T2F_C3F_V3F:
363 stride += 2 * sizeof (GLfloat);
364 stride += 3 * sizeof (GLfloat);
365 stride += 3 * sizeof (GLfloat);
366 break;
367 case GL_T2F_N3F_V3F:
368 stride += 2 * sizeof (GLfloat);
369 stride += 3 * sizeof (GLfloat);
370 stride += 3 * sizeof (GLfloat);
371 break;
372 case GL_T2F_C4F_N3F_V3F:
373 stride += 2 * sizeof (GLfloat);
374 stride += 4 * sizeof (GLfloat);
375 stride += 3 * sizeof (GLfloat);
376 stride += 3 * sizeof (GLfloat);
377 break;
378 case GL_T4F_C4F_N3F_V4F:
379 stride += 4 * sizeof (GLfloat);
380 stride += 4 * sizeof (GLfloat);
381 stride += 3 * sizeof (GLfloat);
382 stride += 4 * sizeof (GLfloat);
383 break;
384 default:
385 break;
386 }
387
388 switch (format) {
389 case GL_T2F_V3F:
390 case GL_T2F_C4UB_V3F:
391 case GL_T2F_C3F_V3F:
392 case GL_T2F_N3F_V3F:
393 case GL_T2F_C4F_N3F_V3F:
394 qfgl_TexCoordPointer (2, GL_FLOAT, stride - 2 * sizeof (GLfloat),
395 ptr);
396 ptr += 2 * sizeof (GLfloat);
397 break;
398 case GL_T4F_V4F:
399 case GL_T4F_C4F_N3F_V4F:
400 qfgl_TexCoordPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat),
401 ptr);
402 ptr += 4 * sizeof (GLfloat);
403 break;
404 default:
405 break;
406 }
407 switch (format) {
408 case GL_C4UB_V2F:
409 case GL_C4UB_V3F:
410 case GL_T2F_C4UB_V3F:
411 qfgl_ColorPointer (4, GL_UNSIGNED_BYTE,
412 stride - 4 * sizeof (GLubyte), ptr);
413 ptr += 4 * sizeof (GLubyte);
414 break;
415 case GL_C3F_V3F:
416 case GL_T2F_C3F_V3F:
417 qfgl_ColorPointer (3, GL_FLOAT, stride - 3 * sizeof (GLfloat),
418 ptr);
419 ptr += 3 * sizeof (GLfloat);
420 break;
421 case GL_C4F_N3F_V3F:
422 case GL_T2F_C4F_N3F_V3F:
423 case GL_T4F_C4F_N3F_V4F:
424 qfgl_ColorPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat),
425 ptr);
426 ptr += 4 * sizeof (GLfloat);
427 break;
428 default:
429 break;
430 }
431 switch (format) {
432 case GL_N3F_V3F:
433 case GL_C4F_N3F_V3F:
434 case GL_T2F_N3F_V3F:
435 case GL_T2F_C4F_N3F_V3F:
436 case GL_T4F_C4F_N3F_V4F:
437 qfgl_NormalPointer (GL_FLOAT, stride - 3 * sizeof (GLfloat), ptr);
438 ptr += 3 * sizeof (GLfloat);
439 break;
440 default:
441 break;
442 }
443 switch (format) {
444 case GL_V2F:
445 case GL_C4UB_V2F:
446 qfgl_VertexPointer (2, GL_FLOAT, stride - 2 * sizeof (GLfloat),
447 ptr);
448 ptr += 2 * sizeof (GLfloat);
449 break;
450 case GL_V3F:
451 case GL_C4UB_V3F:
452 case GL_C3F_V3F:
453 case GL_N3F_V3F:
454 case GL_C4F_N3F_V3F:
455 case GL_T2F_V3F:
456 case GL_T2F_C4UB_V3F:
457 case GL_T2F_C3F_V3F:
458 case GL_T2F_N3F_V3F:
459 case GL_T2F_C4F_N3F_V3F:
460 qfgl_VertexPointer (3, GL_FLOAT, stride - 3 * sizeof (GLfloat),
461 ptr);
462 ptr += 3 * sizeof (GLfloat);
463 break;
464 case GL_T4F_V4F:
465 case GL_T4F_C4F_N3F_V4F:
466 qfgl_VertexPointer (4, GL_FLOAT, stride - 4 * sizeof (GLfloat),
467 ptr);
468 ptr += 4 * sizeof (GLfloat);
469 break;
470 default:
471 break;
472 }
473 }
474
475 static void
qfgl_ArrayElement(GLint i)476 qfgl_ArrayElement (GLint i)
477 {
478 if (texcoord_enabled)
479 texcoord_func ((char*)texcoord_pointer + i * texcoord_stride);
480 if (edgeflag_enabled)
481 qfglEdgeFlagv ((byte*)edgeflag_pointer + i * edgeflag_stride);
482 if (color_enabled)
483 color_func ((char*)color_pointer + i * color_stride);
484 if (normal_enabled)
485 normal_func ((char*)normal_pointer + i * normal_stride);
486 if (index_enabled)
487 index_func ((char*)index_pointer + i * index_stride);
488 if (vertex_enabled)
489 vertex_func ((char*)vertex_pointer + i * vertex_stride);
490 }
491
492 static void
qfgl_DrawArrays(GLenum mode,GLint first,GLsizei count)493 qfgl_DrawArrays (GLenum mode, GLint first, GLsizei count)
494 {
495 GLint i;
496
497 qfglBegin (mode);
498 for (i = first; i < first + count; i++)
499 qfgl_ArrayElement (i);
500 qfglEnd ();
501 }
502
503 static void
qfgl_DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)504 qfgl_DrawElements (GLenum mode, GLsizei count, GLenum type,
505 const GLvoid * indices)
506 {
507 GLsizei i;
508 const GLubyte *ub_indices;
509 const GLushort *us_indices;
510 const GLuint *ui_indices;
511
512 switch (type) {
513 case GL_UNSIGNED_BYTE:
514 ub_indices = indices;
515 for (i = 0; i < count; i++)
516 qfgl_ArrayElement (ub_indices[i]);
517 break;
518 case GL_UNSIGNED_SHORT:
519 us_indices = indices;
520 for (i = 0; i < count; i++)
521 qfgl_ArrayElement (us_indices[i]);
522 break;
523 case GL_UNSIGNED_INT:
524 ui_indices = indices;
525 for (i = 0; i < count; i++)
526 qfgl_ArrayElement (ui_indices[i]);
527 break;
528 default:
529 break;
530 }
531 }
532
533 static void
qfgl_DrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices)534 qfgl_DrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count,
535 GLenum type, const GLvoid * indices)
536 {
537 GLsizei i;
538 const GLubyte *ub_indices;
539 const GLushort *us_indices;
540 const GLuint *ui_indices;
541
542 switch (type) {
543 case GL_UNSIGNED_BYTE:
544 ub_indices = indices;
545 for (i = 0; i < count; i++)
546 if (ub_indices[i] >= start && ub_indices[i] <= end)
547 qfgl_ArrayElement (ub_indices[i]);
548 break;
549 case GL_UNSIGNED_SHORT:
550 us_indices = indices;
551 for (i = 0; i < count; i++)
552 if (us_indices[i] >= start && us_indices[i] <= end)
553 qfgl_ArrayElement (us_indices[i]);
554 break;
555 case GL_UNSIGNED_INT:
556 ui_indices = indices;
557 for (i = 0; i < count; i++)
558 if (ui_indices[i] >= start && ui_indices[i] <= end)
559 qfgl_ArrayElement (ui_indices[i]);
560 break;
561 default:
562 break;
563 }
564 }
565
566 static void
client_state(GLenum cap,GLboolean state)567 client_state (GLenum cap, GLboolean state)
568 {
569 switch (cap) {
570 case GL_VERTEX_ARRAY:
571 vertex_enabled = state;
572 break;
573 case GL_NORMAL_ARRAY:
574 normal_enabled = state;
575 break;
576 case GL_COLOR_ARRAY:
577 color_enabled = state;
578 break;
579 case GL_INDEX_ARRAY:
580 index_enabled = state;
581 break;
582 case GL_TEXTURE_COORD_ARRAY:
583 texcoord_enabled = state;
584 break;
585 case GL_EDGE_FLAG_ARRAY:
586 edgeflag_enabled = state;
587 break;
588 }
589 }
590
591 static void
qfgl_EnableClientState(GLenum cap)592 qfgl_EnableClientState (GLenum cap)
593 {
594 client_state (cap, GL_TRUE);
595 }
596
597 static void
qfgl_DisableClientState(GLenum cap)598 qfgl_DisableClientState (GLenum cap)
599 {
600 client_state (cap, GL_FALSE);
601 }
602
603 static void
qfgl_GetPointerv(GLenum pname,void ** params)604 qfgl_GetPointerv (GLenum pname, void **params)
605 {
606 Sys_Error ("GetPointerv not implemented");
607 }
608
609 static void
qfgl_PopClientAttrib(void)610 qfgl_PopClientAttrib (void)
611 {
612 Sys_Error ("PopClientAttrib not implemented");
613 }
614
615 static void
qfgl_PushClientAttrib(GLbitfield mask)616 qfgl_PushClientAttrib (GLbitfield mask)
617 {
618 Sys_Error ("PushClientAttrib not implemented");
619 }
620
621 struct {
622 const char *name;
623 void *func;
624 } qfgl_functions [] = {
625 {"glColorPointer", qfgl_ColorPointer},
626 {"glEdgeFlagPointer", qfgl_EdgeFlagPointer},
627 {"glIndexPointer", qfgl_IndexPointer},
628 {"glNormalPointer", qfgl_NormalPointer},
629 {"glTexCoordPointer", qfgl_TexCoordPointer},
630 {"glVertexPointer", qfgl_VertexPointer},
631 {"glInterleavedArrays", qfgl_InterleavedArrays},
632 {"glArrayElement", qfgl_ArrayElement},
633 {"glDrawArrays", qfgl_DrawArrays},
634 {"glDrawElements", qfgl_DrawElements},
635 {"glDrawRangeElements", qfgl_DrawRangeElements},
636 {"glEnableClientState", qfgl_EnableClientState},
637 {"glDisableClientState", qfgl_DisableClientState},
638 {"glGetPointerv", qfgl_GetPointerv},
639 {"glPopClientAttrib", qfgl_PopClientAttrib},
640 {"glPushClientAttrib", qfgl_PushClientAttrib},
641 };
642