VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/packer/pack_client.c@ 21216

Last change on this file since 21216 was 20970, checked in by vboxsync, 16 years ago

crOpenGL: fix incorrect rendering of glDrawRangeElements

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 13.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "packer.h"
8#include "cr_opcodes.h"
9#include "cr_version.h"
10
11/*
12 * Expand glArrayElement into crPackVertex/Color/Normal/etc.
13 */
14void
15crPackExpandArrayElement(GLint index, CRClientState *c)
16{
17 unsigned char *p;
18 int unit;
19
20 if (c->array.e.enabled)
21 {
22 crPackEdgeFlagv(c->array.e.p + index * c->array.e.stride);
23 }
24 for (unit = 0; unit < CR_MAX_TEXTURE_UNITS; unit++)
25 {
26 if (c->array.t[unit].enabled)
27 {
28 p = c->array.t[unit].p + index * c->array.t[unit].stride;
29 switch (c->array.t[unit].type)
30 {
31 case GL_SHORT:
32 switch (c->array.t[c->curClientTextureUnit].size)
33 {
34 case 1: crPackMultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
35 case 2: crPackMultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
36 case 3: crPackMultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
37 case 4: crPackMultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
38 }
39 break;
40 case GL_INT:
41 switch (c->array.t[c->curClientTextureUnit].size)
42 {
43 case 1: crPackMultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
44 case 2: crPackMultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
45 case 3: crPackMultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
46 case 4: crPackMultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
47 }
48 break;
49 case GL_FLOAT:
50 switch (c->array.t[c->curClientTextureUnit].size)
51 {
52 case 1: crPackMultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
53 case 2: crPackMultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
54 case 3: crPackMultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
55 case 4: crPackMultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
56 }
57 break;
58 case GL_DOUBLE:
59 switch (c->array.t[c->curClientTextureUnit].size)
60 {
61 case 1: crPackMultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
62 case 2: crPackMultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
63 case 3: crPackMultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
64 case 4: crPackMultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
65 }
66 break;
67 }
68 }
69 } /* loop over texture units */
70
71 if (c->array.i.enabled)
72 {
73 p = c->array.i.p + index * c->array.i.stride;
74 switch (c->array.i.type)
75 {
76 case GL_SHORT: crPackIndexsv((GLshort *)p); break;
77 case GL_INT: crPackIndexiv((GLint *)p); break;
78 case GL_FLOAT: crPackIndexfv((GLfloat *)p); break;
79 case GL_DOUBLE: crPackIndexdv((GLdouble *)p); break;
80 }
81 }
82 if (c->array.c.enabled)
83 {
84 p = c->array.c.p + index * c->array.c.stride;
85 switch (c->array.c.type)
86 {
87 case GL_BYTE:
88 switch (c->array.c.size)
89 {
90 case 3: crPackColor3bv((GLbyte *)p); break;
91 case 4: crPackColor4bv((GLbyte *)p); break;
92 }
93 break;
94 case GL_UNSIGNED_BYTE:
95 switch (c->array.c.size)
96 {
97 case 3: crPackColor3ubv((GLubyte *)p); break;
98 case 4: crPackColor4ubv((GLubyte *)p); break;
99 }
100 break;
101 case GL_SHORT:
102 switch (c->array.c.size)
103 {
104 case 3: crPackColor3sv((GLshort *)p); break;
105 case 4: crPackColor4sv((GLshort *)p); break;
106 }
107 break;
108 case GL_UNSIGNED_SHORT:
109 switch (c->array.c.size)
110 {
111 case 3: crPackColor3usv((GLushort *)p); break;
112 case 4: crPackColor4usv((GLushort *)p); break;
113 }
114 break;
115 case GL_INT:
116 switch (c->array.c.size)
117 {
118 case 3: crPackColor3iv((GLint *)p); break;
119 case 4: crPackColor4iv((GLint *)p); break;
120 }
121 break;
122 case GL_UNSIGNED_INT:
123 switch (c->array.c.size)
124 {
125 case 3: crPackColor3uiv((GLuint *)p); break;
126 case 4: crPackColor4uiv((GLuint *)p); break;
127 }
128 break;
129 case GL_FLOAT:
130 switch (c->array.c.size)
131 {
132 case 3: crPackColor3fv((GLfloat *)p); break;
133 case 4: crPackColor4fv((GLfloat *)p); break;
134 }
135 break;
136 case GL_DOUBLE:
137 switch (c->array.c.size)
138 {
139 case 3: crPackColor3dv((GLdouble *)p); break;
140 case 4: crPackColor4dv((GLdouble *)p); break;
141 }
142 break;
143 }
144 }
145 if (c->array.n.enabled)
146 {
147 p = c->array.n.p + index * c->array.n.stride;
148 switch (c->array.n.type)
149 {
150 case GL_BYTE: crPackNormal3bv((GLbyte *)p); break;
151 case GL_SHORT: crPackNormal3sv((GLshort *)p); break;
152 case GL_INT: crPackNormal3iv((GLint *)p); break;
153 case GL_FLOAT: crPackNormal3fv((GLfloat *)p); break;
154 case GL_DOUBLE: crPackNormal3dv((GLdouble *)p); break;
155 }
156 }
157#ifdef CR_EXT_secondary_color
158 if (c->array.s.enabled)
159 {
160 p = c->array.s.p + index * c->array.s.stride;
161 switch (c->array.s.type)
162 {
163 case GL_BYTE:
164 crPackSecondaryColor3bvEXT((GLbyte *)p); break;
165 case GL_UNSIGNED_BYTE:
166 crPackSecondaryColor3ubvEXT((GLubyte *)p); break;
167 case GL_SHORT:
168 crPackSecondaryColor3svEXT((GLshort *)p); break;
169 case GL_UNSIGNED_SHORT:
170 crPackSecondaryColor3usvEXT((GLushort *)p); break;
171 case GL_INT:
172 crPackSecondaryColor3ivEXT((GLint *)p); break;
173 case GL_UNSIGNED_INT:
174 crPackSecondaryColor3uivEXT((GLuint *)p); break;
175 case GL_FLOAT:
176 crPackSecondaryColor3fvEXT((GLfloat *)p); break;
177 case GL_DOUBLE:
178 crPackSecondaryColor3dvEXT((GLdouble *)p); break;
179 }
180 }
181#endif
182 if (c->array.v.enabled)
183 {
184 p = c->array.v.p + (index * c->array.v.stride);
185 switch (c->array.v.type)
186 {
187 case GL_SHORT:
188 switch (c->array.v.size)
189 {
190 case 2: crPackVertex2svBBOX_COUNT((GLshort *)p); break;
191 case 3: crPackVertex3svBBOX_COUNT((GLshort *)p); break;
192 case 4: crPackVertex4svBBOX_COUNT((GLshort *)p); break;
193 }
194 break;
195 case GL_INT:
196 switch (c->array.v.size)
197 {
198 case 2: crPackVertex2ivBBOX_COUNT((GLint *)p); break;
199 case 3: crPackVertex3ivBBOX_COUNT((GLint *)p); break;
200 case 4: crPackVertex4ivBBOX_COUNT((GLint *)p); break;
201 }
202 break;
203 case GL_FLOAT:
204 switch (c->array.v.size)
205 {
206 case 2: crPackVertex2fvBBOX_COUNT((GLfloat *)p); break;
207 case 3: crPackVertex3fvBBOX_COUNT((GLfloat *)p); break;
208 case 4: crPackVertex4fvBBOX_COUNT((GLfloat *)p); break;
209 }
210 break;
211 case GL_DOUBLE:
212 switch (c->array.v.size)
213 {
214 case 2: crPackVertex2dvBBOX_COUNT((GLdouble *)p); break;
215 case 3: crPackVertex3dvBBOX_COUNT((GLdouble *)p); break;
216 case 4: crPackVertex4dvBBOX_COUNT((GLdouble *)p); break;
217 }
218 break;
219 }
220 }
221}
222
223
224void
225crPackExpandDrawArrays(GLenum mode, GLint first, GLsizei count, CRClientState *c)
226{
227 int i;
228
229 if (count < 0)
230 {
231 __PackError(__LINE__, __FILE__, GL_INVALID_VALUE, "crPackDrawArrays(negative count)");
232 return;
233 }
234
235 if (mode > GL_POLYGON)
236 {
237 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM, "crPackDrawArrays(bad mode)");
238 return;
239 }
240
241 crPackBegin(mode);
242 for (i=0; i<count; i++)
243 {
244 crPackExpandArrayElement(first + i, c);
245 }
246 crPackEnd();
247}
248
249
250/*
251 * Really pack glDrawElements (for server-side vertex arrays)
252 * Note: we pack the pointer (which is actually an index into the server-side
253 * vertex buffer) and not the actual indices.
254 */
255void PACK_APIENTRY
256crPackDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
257{
258 unsigned char *data_ptr;
259 int packet_length = sizeof(int) + sizeof(mode) + sizeof(count) + sizeof(type) + sizeof(GLintptrARB);
260 data_ptr = (unsigned char *) crPackAlloc(packet_length);
261 WRITE_DATA( 0, GLenum, CR_DRAWELEMENTS_EXTEND_OPCODE );
262 WRITE_DATA( 4, GLenum, mode );
263 WRITE_DATA( 8, GLsizei, count);
264 WRITE_DATA( 12, GLenum, type);
265 WRITE_DATA( 16, GLsizeiptrARB, (GLsizeiptrARB) indices );
266 crHugePacket( CR_EXTEND_OPCODE, data_ptr );
267 crPackFree( data_ptr );
268}
269
270
271/**
272 * Expand glDrawElements into crPackBegin/Vertex/End, etc commands.
273 * Note: if mode==999, don't call glBegin/glEnd.
274 */
275void
276crPackExpandDrawElements(GLenum mode, GLsizei count, GLenum type,
277 const GLvoid *indices, CRClientState *c)
278{
279 int i;
280
281 if (count < 0)
282 {
283 __PackError(__LINE__, __FILE__, GL_INVALID_VALUE,
284 "crPackDrawElements(negative count)");
285 return;
286 }
287
288 if (mode > GL_POLYGON && mode != 999)
289 {
290 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM,
291 "crPackDrawElements(bad mode)");
292 return;
293 }
294
295 if (type != GL_UNSIGNED_BYTE &&
296 type != GL_UNSIGNED_SHORT &&
297 type != GL_UNSIGNED_INT)
298 {
299 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM,
300 "crPackDrawElements(bad type)");
301 return;
302 }
303
304 if (mode != 999)
305 crPackBegin(mode);
306
307 switch (type) {
308 case GL_UNSIGNED_BYTE:
309 {
310 const GLubyte *p = (const GLubyte *) indices;
311 for (i = 0; i < count; i++)
312 crPackExpandArrayElement(p[i], c);
313 }
314 break;
315 case GL_UNSIGNED_SHORT:
316 {
317 const GLushort *p = (const GLushort *) indices;
318 for (i=0; i<count; i++)
319 crPackExpandArrayElement(p[i], c);
320 }
321 break;
322 case GL_UNSIGNED_INT:
323 {
324 const GLuint *p = (const GLuint *) indices;
325 for (i = 0; i < count; i++)
326 crPackExpandArrayElement(p[i], c);
327 }
328 break;
329 default:
330 __PackError( __LINE__, __FILE__, GL_INVALID_ENUM,
331 "crPackDrawElements(bad type)");
332 break;
333 }
334
335 if (mode != 999)
336 crPackEnd();
337}
338
339
340/**
341 * Convert a glDrawElements command into a sequence of ArrayElement() calls.
342 * NOTE: Caller must issue the glBegin/glEnd.
343 */
344void
345crPackUnrollDrawElements(GLsizei count, GLenum type,
346 const GLvoid *indices)
347{
348 int i;
349
350 switch (type) {
351 case GL_UNSIGNED_BYTE:
352 {
353 const GLubyte *p = (const GLubyte *) indices;
354 for (i = 0; i < count; i++)
355 crPackArrayElement(p[i]);
356 }
357 break;
358 case GL_UNSIGNED_SHORT:
359 {
360 const GLushort *p = (const GLushort *) indices;
361 for (i = 0; i < count; i++)
362 crPackArrayElement(p[i]);
363 }
364 break;
365 case GL_UNSIGNED_INT:
366 {
367 const GLuint *p = (const GLuint *) indices;
368 for (i = 0; i < count; i++)
369 crPackArrayElement(p[i]);
370 }
371 break;
372 default:
373 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM,
374 "crPackUnrollDrawElements(bad type)");
375 }
376}
377
378
379
380/*
381 * Really pack glDrawRangeElements (for server-side vertex arrays)
382 * Note: we pack the pointer (which is actually an index into the server-side
383 * vertex buffer) and not the actual indices.
384 */
385void PACK_APIENTRY
386crPackDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
387 GLenum type, const GLvoid *indices)
388{
389 unsigned char *data_ptr;
390 int packet_length = sizeof(int) + sizeof(mode) + sizeof(start)
391 + sizeof(end) + sizeof(count) + sizeof(type) + sizeof(GLintptrARB);
392
393 data_ptr = (unsigned char *) crPackAlloc(packet_length);
394 WRITE_DATA( 0, GLenum, CR_DRAWRANGEELEMENTS_EXTEND_OPCODE );
395 WRITE_DATA( 4, GLenum, mode );
396 WRITE_DATA( 8, GLuint, start );
397 WRITE_DATA( 12, GLuint, end );
398 WRITE_DATA( 16, GLsizei, count );
399 WRITE_DATA( 20, GLenum, type );
400 WRITE_DATA( 24, GLsizeiptrARB, (GLsizeiptr) indices );
401 crHugePacket( CR_EXTEND_OPCODE, data_ptr );
402 crPackFree( data_ptr );
403}
404
405
406/*
407 * glDrawRangeElements, expanded into crPackBegin/Vertex/End/etc.
408 */
409void
410crPackExpandDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, CRClientState *c)
411{
412 int i;
413 GLubyte *p = (GLubyte *)indices;
414
415 (void) end;
416
417 if (count < 0)
418 {
419 __PackError(__LINE__, __FILE__, GL_INVALID_VALUE, "crPackDrawRangeElements(negative count)");
420 return;
421 }
422
423 if (mode > GL_POLYGON)
424 {
425 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM, "crPackDrawRangeElements(bad mode)");
426 return;
427 }
428
429 if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
430 {
431 __PackError(__LINE__, __FILE__, GL_INVALID_ENUM, "crPackDrawRangeElements(bad type)");
432 return;
433 }
434
435 crPackBegin(mode);
436 switch (type)
437 {
438 case GL_UNSIGNED_BYTE:
439 for (i=0; i<count; i++)
440 {
441 crPackExpandArrayElement((GLint) *p++, c);
442 }
443 break;
444 case GL_UNSIGNED_SHORT:
445 for (i=0; i<count; i++)
446 {
447 crPackExpandArrayElement((GLint) * (GLushort *) p, c);
448 p += sizeof(GLushort);
449 }
450 break;
451 case GL_UNSIGNED_INT:
452 for (i=0; i<count; i++)
453 {
454 crPackExpandArrayElement((GLint) * (GLuint *) p, c);
455 p += sizeof(GLuint);
456 }
457 break;
458 default:
459 crError( "this can't happen: crPackDrawRangeElements" );
460 break;
461 }
462 crPackEnd();
463}
464
465
466#ifdef CR_EXT_multi_draw_arrays
467/*
468 * Pack real DrawArrays commands.
469 */
470void PACK_APIENTRY
471crPackMultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count,
472 GLsizei primcount )
473{
474 GLint i;
475 for (i = 0; i < primcount; i++) {
476 if (count[i] > 0) {
477 crPackDrawArrays(mode, first[i], count[i]);
478 }
479 }
480}
481
482
483/*
484 * Pack with crPackBegin/Vertex/End/etc.
485 */
486void
487crPackExpandMultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count,
488 GLsizei primcount, CRClientState *c )
489{
490 GLint i;
491 for (i = 0; i < primcount; i++) {
492 if (count[i] > 0) {
493 crPackExpandDrawArrays(mode, first[i], count[i], c);
494 }
495 }
496}
497
498
499/*
500 * Pack real DrawElements commands.
501 */
502void PACK_APIENTRY
503crPackMultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
504 const GLvoid **indices, GLsizei primcount )
505{
506 GLint i;
507 for (i = 0; i < primcount; i++) {
508 if (count[i] > 0) {
509 crPackDrawElements(mode, count[i], type, indices[i]);
510 }
511 }
512}
513
514
515/*
516 * Pack with crPackBegin/Vertex/End/etc.
517 */
518void
519crPackExpandMultiDrawElementsEXT( GLenum mode, const GLsizei *count,
520 GLenum type, const GLvoid **indices,
521 GLsizei primcount, CRClientState *c )
522{
523 GLint i;
524 for (i = 0; i < primcount; i++) {
525 if (count[i] > 0) {
526 crPackExpandDrawElements(mode, count[i], type, indices[i], c);
527 }
528 }
529}
530#endif /* CR_EXT_multi_draw_arrays */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette