VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_teximage.c@ 16107

Last change on this file since 16107 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 37.6 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
8#include "state.h"
9#include "state/cr_statetypes.h"
10#include "state/cr_texture.h"
11#include "cr_pixeldata.h"
12#include "cr_string.h"
13#include "cr_mem.h"
14#include "cr_version.h"
15#include "state_internals.h"
16
17
18
19static int
20bitcount(int value)
21{
22 int bits = 0;
23 for (; value > 0; value >>= 1) {
24 if (value & 0x1)
25 bits++;
26 }
27 return bits;
28}
29
30
31/**
32 * Return 1 if the target is a proxy target, 0 otherwise.
33 */
34static GLboolean
35IsProxyTarget(GLenum target)
36{
37 return (target == GL_PROXY_TEXTURE_1D ||
38 target == GL_PROXY_TEXTURE_2D ||
39 target == GL_PROXY_TEXTURE_3D ||
40 target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
41 target == GL_PROXY_TEXTURE_CUBE_MAP);
42}
43
44
45/**
46 * Test if a texture width, height or depth is legal.
47 * It must be true that 0 <= size <= max.
48 * Furthermore, if the ARB_texture_non_power_of_two extension isn't
49 * present, size must also be a power of two.
50 */
51static GLboolean
52isLegalSize(CRContext *g, GLsizei size, GLsizei max)
53{
54 if (size < 0 || size > max)
55 return GL_FALSE;
56 if (!g->extensions.ARB_texture_non_power_of_two) {
57 /* check for power of two */
58 if (size > 0 && bitcount(size) != 1)
59 return GL_FALSE;
60 }
61 return GL_TRUE;
62}
63
64
65/**
66 * Return the max legal texture level parameter for the given target.
67 */
68static GLint
69MaxTextureLevel(CRContext *g, GLenum target)
70{
71 CRTextureState *t = &(g->texture);
72 switch (target) {
73 case GL_TEXTURE_1D:
74 case GL_PROXY_TEXTURE_1D:
75 case GL_TEXTURE_2D:
76 case GL_PROXY_TEXTURE_2D:
77 return t->maxLevel;
78 case GL_TEXTURE_3D:
79 case GL_PROXY_TEXTURE_3D:
80 return t->max3DLevel;
81 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
82 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
83 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
84 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
85 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
86 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
87 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
88 return t->maxCubeMapLevel;
89 case GL_TEXTURE_RECTANGLE_NV:
90 case GL_PROXY_TEXTURE_RECTANGLE_NV:
91 return t->maxRectLevel;
92 default:
93 return 0;
94 }
95}
96
97
98/**
99 * If GL_GENERATE_MIPMAP_SGIS is true and we modify the base level texture
100 * image we have to finish the mipmap.
101 * All we really have to do is fill in the width/height/format/etc for the
102 * remaining image levels. The image data doesn't matter here - the back-
103 * end OpenGL library will fill those in.
104 */
105static void
106generate_mipmap(CRTextureObj *tobj, GLenum target)
107{
108 CRTextureLevel *levels;
109 GLint level, width, height, depth;
110
111 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
112 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
113 levels = tobj->level[target - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB];
114 }
115 else {
116 levels = tobj->level[0];
117 }
118
119 width = levels[tobj->baseLevel].width;
120 height = levels[tobj->baseLevel].height;
121 depth = levels[tobj->baseLevel].depth;
122
123 for (level = tobj->baseLevel + 1; level <= tobj->maxLevel; level++)
124 {
125 if (width > 1)
126 width /= 2;
127 if (height > 1)
128 height /= 2;
129 if (depth > 1)
130 depth /= 2;
131 levels[level].width = width;
132 levels[level].height = height;
133 levels[level].depth = depth;
134 levels[level].internalFormat = levels[tobj->baseLevel].internalFormat;
135 levels[level].format = levels[tobj->baseLevel].format;
136 levels[level].type = levels[tobj->baseLevel].type;
137#ifdef CR_ARB_texture_compression
138 levels[level].compressed = levels[tobj->baseLevel].compressed;
139#endif
140 levels[level].texFormat = levels[tobj->baseLevel].texFormat;
141 if (width == 1 && height == 1 && depth == 1)
142 break;
143 }
144
145 /* Set this flag so when we do the state diff, we enable GENERATE_MIPMAP
146 * prior to calling diff.TexImage().
147 */
148 levels[tobj->baseLevel].generateMipmap = GL_TRUE;
149}
150
151
152/**
153 * Given a texture target and level, return pointers to the corresponding
154 * texture object and texture image level.
155 */
156void
157crStateGetTextureObjectAndImage(CRContext *g, GLenum texTarget, GLint level,
158 CRTextureObj **obj, CRTextureLevel **img)
159{
160 CRTextureState *t = &(g->texture);
161 CRTextureUnit *unit = t->unit + t->curTextureUnit;
162
163 switch (texTarget) {
164 case GL_TEXTURE_1D:
165 *obj = unit->currentTexture1D;
166 *img = unit->currentTexture1D->level[0] + level;
167 return;
168 case GL_PROXY_TEXTURE_1D:
169 *obj = &(t->proxy1D);
170 *img = t->proxy1D.level[0] + level;
171 return;
172 case GL_TEXTURE_2D:
173 *obj = unit->currentTexture2D;
174 *img = unit->currentTexture2D->level[0] + level;
175 return;
176 case GL_PROXY_TEXTURE_2D:
177 *obj = &(t->proxy2D);
178 *img = t->proxy2D.level[0] + level;
179 return;
180 case GL_TEXTURE_3D:
181 *obj = unit->currentTexture3D;
182 *img = unit->currentTexture3D->level[0] + level;
183 return;
184 case GL_PROXY_TEXTURE_3D:
185 *obj = &(t->proxy3D);
186 *img = t->proxy3D.level[0] + level;
187 return;
188 default:
189 /* fall-through */
190 ;
191 }
192
193#ifdef CR_NV_texture_rectangle
194 if (g->extensions.NV_texture_rectangle) {
195 switch (texTarget) {
196 case GL_PROXY_TEXTURE_RECTANGLE_NV:
197 *obj = &(t->proxyRect);
198 *img = t->proxyRect.level[0] + level;
199 return;
200 case GL_TEXTURE_RECTANGLE_NV:
201 *obj = unit->currentTextureRect;
202 *img = unit->currentTextureRect->level[0] + level;
203 return;
204 default:
205 /* fall-through */
206 ;
207 }
208 }
209#endif
210
211#ifdef CR_ARB_texture_cube_map
212 if (g->extensions.ARB_texture_cube_map) {
213 switch (texTarget) {
214 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
215 *obj = &(t->proxyCubeMap);
216 *img = t->proxyCubeMap.level[0] + level;
217 return;
218 case GL_TEXTURE_CUBE_MAP_ARB:
219 *obj = unit->currentTextureCubeMap;
220 *img = NULL;
221 return;
222 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
223 *obj = unit->currentTextureCubeMap;
224 *img = unit->currentTextureCubeMap->level[0] + level;
225 return;
226 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
227 *obj = unit->currentTextureCubeMap;
228 *img = unit->currentTextureCubeMap->level[1] + level;
229 return;
230 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
231 *obj = unit->currentTextureCubeMap;
232 *img = unit->currentTextureCubeMap->level[2] + level;
233 return;
234 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
235 *obj = unit->currentTextureCubeMap;
236 *img = unit->currentTextureCubeMap->level[3] + level;
237 return;
238 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
239 *obj = unit->currentTextureCubeMap;
240 *img = unit->currentTextureCubeMap->level[4] + level;
241 return;
242 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
243 *obj = unit->currentTextureCubeMap;
244 *img = unit->currentTextureCubeMap->level[5] + level;
245 return;
246 default:
247 /* fall-through */
248 ;
249 }
250 }
251#endif
252
253 *obj = NULL;
254 *img = NULL;
255}
256
257
258/**
259 * Do parameter error checking for glTexImagexD functions.
260 * We'll call crStateError if we detect any errors, unless it's a proxy target.
261 * Return GL_TRUE if any errors, GL_FALSE if no errors.
262 */
263static GLboolean
264ErrorCheckTexImage(GLuint dims, GLenum target, GLint level,
265 GLsizei width, GLsizei height, GLsizei depth, GLint border)
266{
267 CRContext *g = GetCurrentContext();
268
269 if (g->current.inBeginEnd)
270 {
271 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
272 "glTexImage%uD called in Begin/End", dims);
273 return GL_TRUE;
274 }
275
276 /*
277 * Test target
278 */
279 switch (target)
280 {
281 case GL_TEXTURE_1D:
282 case GL_PROXY_TEXTURE_1D:
283 if (dims != 1) {
284 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
285 "glTexImage(invalid target=0x%x)", target);
286 return GL_TRUE;
287 }
288 break;
289 case GL_TEXTURE_2D:
290 case GL_PROXY_TEXTURE_2D:
291 if (dims != 2) {
292 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
293 "glTexImage(invalid target=0x%x)", target);
294 return GL_TRUE;
295 }
296 break;
297 case GL_TEXTURE_3D:
298 case GL_PROXY_TEXTURE_3D:
299 if (dims != 3) {
300 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
301 "glTexImage(invalid target=0x%x)", target);
302 return GL_TRUE;
303 }
304 break;
305#ifdef CR_NV_texture_rectangle
306 case GL_TEXTURE_RECTANGLE_NV:
307 case GL_PROXY_TEXTURE_RECTANGLE_NV:
308 if (dims != 2 || !g->extensions.NV_texture_rectangle) {
309 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
310 "glTexImage2D(invalid target=0x%x)", target);
311 return GL_TRUE;
312 }
313 break;
314#endif
315#ifdef CR_ARB_texture_cube_map
316 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
317 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
318 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
319 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
320 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
321 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
322 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
323 if (dims != 2 || !g->extensions.ARB_texture_cube_map) {
324 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
325 "glTexImage2D(invalid target=0x%x)", target);
326 return GL_TRUE;
327 }
328 break;
329#endif
330 default:
331 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
332 "glTexImage%uD(invalid target=0x%x)", dims, target);
333 return GL_TRUE;
334 }
335
336 /*
337 * Test level
338 */
339 if (level < 0 || level > MaxTextureLevel(g, target)) {
340 if (!IsProxyTarget(target))
341 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
342 "glTexImage%uD(level=%d)", dims, level);
343 return GL_TRUE;
344 }
345
346 /*
347 * Test border
348 */
349 if (border != 0 && border != 1) {
350 if (!IsProxyTarget(target))
351 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
352 "glTexImage%uD(border=%d)", dims, border);
353 return GL_TRUE;
354 }
355
356 if ((target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
357 target == GL_TEXTURE_RECTANGLE_NV) && border != 0) {
358 if (!IsProxyTarget(target))
359 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
360 "glTexImage2D(border=%d)", border);
361 return GL_TRUE;
362 }
363
364 /*
365 * Test width, height, depth
366 */
367 if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
368 if (!isLegalSize(g, width - 2 * border, g->limits.maxTextureSize)) {
369 if (!IsProxyTarget(target))
370 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
371 "glTexImage1D(width=%d)", width);
372 return GL_TRUE;
373 }
374 }
375 else if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
376 if (!isLegalSize(g, width - 2 * border, g->limits.maxTextureSize) ||
377 !isLegalSize(g, height - 2 * border, g->limits.maxTextureSize)) {
378 if (!IsProxyTarget(target))
379 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
380 "glTexImage2D(width=%d, height=%d)", width, height);
381 return GL_TRUE;
382 }
383 }
384 else if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
385 if (!isLegalSize(g, width - 2 * border, g->limits.max3DTextureSize) ||
386 !isLegalSize(g, height - 2 * border, g->limits.max3DTextureSize) ||
387 !isLegalSize(g, depth - 2 * border, g->limits.max3DTextureSize)) {
388 if (!IsProxyTarget(target))
389 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
390 "glTexImage3D(width=%d, height=%d, depth=%d)",
391 width, height, depth);
392 return GL_TRUE;
393 }
394 }
395 else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
396 target == GL_TEXTURE_RECTANGLE_NV) {
397 if (width < 0 || width > (int) g->limits.maxRectTextureSize ||
398 height < 0 || height > (int) g->limits.maxRectTextureSize) {
399 if (!IsProxyTarget(target))
400 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
401 "glTexImage2D(width=%d, height=%d)", width, height);
402 return GL_TRUE;
403 }
404 }
405 else {
406 /* cube map */
407 if (!isLegalSize(g, width - 2*border, g->limits.maxCubeMapTextureSize) ||
408 !isLegalSize(g, height - 2*border, g->limits.maxCubeMapTextureSize) ||
409 width != height) {
410 if (!IsProxyTarget(target))
411 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
412 "glTexImage2D(width=%d, height=%d)", width, height);
413 return GL_TRUE;
414 }
415 }
416
417 /* OK, no errors */
418 return GL_FALSE;
419}
420
421
422/**
423 * Do error check for glTexSubImage() functions.
424 * We'll call crStateError if we detect any errors.
425 * Return GL_TRUE if any errors, GL_FALSE if no errors.
426 */
427static GLboolean
428ErrorCheckTexSubImage(GLuint dims, GLenum target, GLint level,
429 GLint xoffset, GLint yoffset, GLint zoffset,
430 GLsizei width, GLsizei height, GLsizei depth)
431{
432 CRContext *g = GetCurrentContext();
433 CRTextureObj *tobj;
434 CRTextureLevel *tl;
435
436 if (g->current.inBeginEnd) {
437 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
438 "glTexSubImage%uD called in Begin/End", dims);
439 return GL_TRUE;
440 }
441
442 if (dims == 1) {
443 if (target != GL_TEXTURE_1D) {
444 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
445 "glTexSubImage1D(target=0x%x)", target);
446 return GL_TRUE;
447 }
448 }
449 else if (dims == 2) {
450 if (target != GL_TEXTURE_2D &&
451 target != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
452 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
453 target != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
454 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
455 target != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
456 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB &&
457 target != GL_TEXTURE_RECTANGLE_NV) {
458 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
459 "glTexSubImage2D(target=0x%x)", target);
460 return GL_TRUE;
461 }
462 }
463 else if (dims == 3) {
464 if (target != GL_TEXTURE_3D) {
465 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
466 "glTexSubImage3D(target=0x%x)", target);
467 return GL_TRUE;
468 }
469 }
470
471 /* test level */
472 if (level < 0 || level > MaxTextureLevel(g, target)) {
473 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
474 "glTexSubImage%uD(level=%d)", dims, level);
475 return GL_TRUE;
476 }
477
478 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
479 if (!tobj || !tl) {
480 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
481 "glTexSubImage%uD(target or level)", dims);
482 return GL_TRUE;
483 }
484
485 /* test x/y/zoffset and size */
486 if (xoffset < -tl->border || xoffset + width > tl->width) {
487 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
488 "glTexSubImage%uD(xoffset=%d + width=%d > %d)",
489 dims, xoffset, width, tl->width);
490 return GL_TRUE;
491 }
492 if (dims > 1 && (yoffset < -tl->border || yoffset + height > tl->height)) {
493 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
494 "glTexSubImage%uD(yoffset=%d + height=%d > %d)",
495 dims, yoffset, height, tl->height);
496 return GL_TRUE;
497 }
498 if (dims > 2 && (zoffset < -tl->border || zoffset + depth > tl->depth)) {
499 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
500 "glTexSubImage%uD(zoffset=%d and/or depth=%d)",
501 dims, zoffset, depth);
502 return GL_TRUE;
503 }
504
505 /* OK, no errors */
506 return GL_FALSE;
507}
508
509
510
511void STATE_APIENTRY
512crStateTexImage1D(GLenum target, GLint level, GLint internalFormat,
513 GLsizei width, GLint border, GLenum format,
514 GLenum type, const GLvoid * pixels)
515{
516 CRContext *g = GetCurrentContext();
517 CRTextureState *t = &(g->texture);
518 CRClientState *c = &(g->client);
519 CRTextureObj *tobj;
520 CRTextureLevel *tl;
521 CRStateBits *sb = GetCurrentBits();
522 CRTextureBits *tb = &(sb->texture);
523
524 FLUSH();
525
526 if (ErrorCheckTexImage(1, target, level, width, 1, 1, border)) {
527 if (IsProxyTarget(target)) {
528 /* clear all state, but don't generate error */
529 crStateTextureInitTextureObj(g, &(t->proxy1D), 0, GL_TEXTURE_1D);
530 }
531 else {
532 /* error was already recorded */
533 }
534 return;
535 }
536
537 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
538 CRASSERT(tobj);
539 CRASSERT(tl);
540
541 if (IsProxyTarget(target))
542 tl->bytes = 0;
543 else
544 tl->bytes = crImageSize(format, type, width, 1);
545
546 if (tl->bytes)
547 {
548 /* this is not a proxy texture target so alloc storage */
549 if (tl->img)
550 crFree(tl->img);
551 tl->img = (GLubyte *) crAlloc(tl->bytes);
552 if (!tl->img)
553 {
554 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
555 "glTexImage1D out of memory");
556 return;
557 }
558 if (pixels)
559 crPixelCopy1D((GLvoid *) tl->img, format, type,
560 pixels, format, type, width, &(c->unpack));
561 }
562
563 tl->width = width;
564 tl->height = 1;
565 tl->depth = 1;
566 tl->format = format;
567 tl->border = border;
568 tl->internalFormat = internalFormat;
569 crStateTextureInitTextureFormat(tl, internalFormat);
570 tl->type = type;
571 tl->compressed = GL_FALSE;
572 if (width)
573 tl->bytesPerPixel = tl->bytes / width;
574 else
575 tl->bytesPerPixel = 0;
576
577#ifdef CR_SGIS_generate_mipmap
578 if (level == tobj->baseLevel && tobj->generateMipmap) {
579 generate_mipmap(tobj, target);
580 }
581 else {
582 tl->generateMipmap = GL_FALSE;
583 }
584#endif
585
586 /* XXX may need to do some fine-tuning here for proxy textures */
587 DIRTY(tobj->dirty, g->neg_bitid);
588 DIRTY(tobj->imageBit, g->neg_bitid);
589 DIRTY(tl->dirty, g->neg_bitid);
590 DIRTY(tb->dirty, g->neg_bitid);
591}
592
593
594void STATE_APIENTRY
595crStateTexImage2D(GLenum target, GLint level, GLint internalFormat,
596 GLsizei width, GLsizei height, GLint border,
597 GLenum format, GLenum type, const GLvoid * pixels)
598{
599 CRContext *g = GetCurrentContext();
600 CRTextureState *t = &(g->texture);
601 CRClientState *c = &(g->client);
602 CRTextureObj *tobj = NULL;
603 CRTextureLevel *tl = NULL;
604 CRStateBits *sb = GetCurrentBits();
605 CRTextureBits *tb = &(sb->texture);
606 const int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
607
608 FLUSH();
609
610 /* NOTE: we skip parameter error checking if this is a distributed
611 * texture! The user better provide correct parameters!!!
612 */
613 if (!is_distrib
614 && ErrorCheckTexImage(2, target, level, width, height, 1, border)) {
615 if (IsProxyTarget(target)) {
616 /* clear all state, but don't generate error */
617 crStateTextureInitTextureObj(g, &(t->proxy2D), 0, GL_TEXTURE_2D);
618 }
619 else {
620 /* error was already recorded */
621 }
622 return;
623 }
624
625 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
626 CRASSERT(tobj);
627 CRASSERT(tl);
628
629 /* compute size of image buffer */
630 if (is_distrib) {
631 tl->bytes = crStrlen((char *) pixels) + 1;
632 tl->bytes += crImageSize(format, GL_UNSIGNED_BYTE, width, height);
633 }
634 else if (IsProxyTarget(target)) {
635 tl->bytes = 0;
636 }
637 else {
638 tl->bytes = crImageSize(format, type, width, height);
639 }
640
641 /* allocate the image buffer and fill it */
642 if (tl->bytes)
643 {
644 /* this is not a proxy texture target so alloc storage */
645 if (tl->img)
646 crFree(tl->img);
647 tl->img = (GLubyte *) crAlloc(tl->bytes);
648 if (!tl->img)
649 {
650 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
651 "glTexImage2D out of memory");
652 return;
653 }
654 if (pixels)
655 {
656 if (is_distrib)
657 {
658 crMemcpy((void *) tl->img, (void *) pixels, tl->bytes);
659 }
660 else
661 {
662 crPixelCopy2D(width, height,
663 (GLvoid *) tl->img, format, type, NULL, /* dst */
664 pixels, format, type, &(c->unpack)); /* src */
665 }
666 }
667 }
668
669 tl->width = width;
670 tl->height = height;
671 tl->depth = 1;
672 tl->format = format;
673 tl->internalFormat = internalFormat;
674 crStateTextureInitTextureFormat(tl, internalFormat);
675 tl->border = border;
676 tl->type = type;
677 tl->compressed = GL_FALSE;
678 if (width && height)
679 {
680 if (is_distrib)
681 tl->bytesPerPixel = 3; /* only support GL_RGB */
682 else
683 tl->bytesPerPixel = tl->bytes / (width * height);
684 }
685 else
686 tl->bytesPerPixel = 0;
687
688#ifdef CR_SGIS_generate_mipmap
689 if (level == tobj->baseLevel && tobj->generateMipmap) {
690 generate_mipmap(tobj, target);
691 }
692 else {
693 tl->generateMipmap = GL_FALSE;
694 }
695#endif
696
697 /* XXX may need to do some fine-tuning here for proxy textures */
698 DIRTY(tobj->dirty, g->neg_bitid);
699 DIRTY(tobj->imageBit, g->neg_bitid);
700 DIRTY(tl->dirty, g->neg_bitid);
701 DIRTY(tb->dirty, g->neg_bitid);
702}
703
704
705#if defined( CR_OPENGL_VERSION_1_2 ) || defined( GL_EXT_texture3D )
706void STATE_APIENTRY
707crStateTexImage3D(GLenum target, GLint level,
708 GLint internalFormat,
709 GLsizei width, GLsizei height,
710 GLsizei depth, GLint border,
711 GLenum format, GLenum type, const GLvoid * pixels)
712{
713 CRContext *g = GetCurrentContext();
714 CRTextureState *t = &(g->texture);
715 CRClientState *c = &(g->client);
716 CRTextureObj *tobj = NULL;
717 CRTextureLevel *tl = NULL;
718 CRStateBits *sb = GetCurrentBits();
719 CRTextureBits *tb = &(sb->texture);
720
721 FLUSH();
722
723 if (ErrorCheckTexImage(3, target, level, width, height, depth, border)) {
724 if (IsProxyTarget(target)) {
725 /* clear all state, but don't generate error */
726 crStateTextureInitTextureObj(g, &(t->proxy3D), 0, GL_TEXTURE_3D);
727 }
728 else {
729 /* error was already recorded */
730 }
731 return;
732 }
733
734 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
735 CRASSERT(tobj);
736 CRASSERT(tl);
737
738 if (IsProxyTarget(target))
739 tl->bytes = 0;
740 else
741 tl->bytes = crTextureSize(format, type, width, height, depth);
742
743 if (tl->bytes)
744 {
745 /* this is not a proxy texture target so alloc storage */
746 if (tl->img)
747 crFree(tl->img);
748 tl->img = (GLubyte *) crAlloc(tl->bytes);
749 if (!tl->img)
750 {
751 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
752 "glTexImage3D out of memory");
753 return;
754 }
755 if (pixels)
756 crPixelCopy3D(width, height, depth, (GLvoid *) (tl->img), format, type,
757 NULL, pixels, format, type, &(c->unpack));
758 }
759
760 tl->internalFormat = internalFormat;
761 tl->border = border;
762 tl->width = width;
763 tl->height = height;
764 tl->depth = depth;
765 tl->format = format;
766 tl->type = type;
767 tl->compressed = GL_FALSE;
768
769#ifdef CR_SGIS_generate_mipmap
770 if (level == tobj->baseLevel && tobj->generateMipmap) {
771 generate_mipmap(tobj, target);
772 }
773 else {
774 tl->generateMipmap = GL_FALSE;
775 }
776#endif
777
778 /* XXX may need to do some fine-tuning here for proxy textures */
779 DIRTY(tobj->dirty, g->neg_bitid);
780 DIRTY(tobj->imageBit, g->neg_bitid);
781 DIRTY(tl->dirty, g->neg_bitid);
782 DIRTY(tb->dirty, g->neg_bitid);
783}
784#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
785
786
787#ifdef GL_EXT_texture3D
788void STATE_APIENTRY
789crStateTexImage3DEXT(GLenum target, GLint level,
790 GLenum internalFormat,
791 GLsizei width, GLsizei height, GLsizei depth,
792 GLint border, GLenum format, GLenum type,
793 const GLvoid * pixels)
794{
795 crStateTexImage3D(target, level, (GLint) internalFormat, width, height,
796 depth, border, format, type, pixels);
797}
798#endif /* GL_EXT_texture3D */
799
800
801void STATE_APIENTRY
802crStateTexSubImage1D(GLenum target, GLint level, GLint xoffset,
803 GLsizei width, GLenum format,
804 GLenum type, const GLvoid * pixels)
805{
806 CRContext *g = GetCurrentContext();
807 CRTextureState *t = &(g->texture);
808 CRClientState *c = &(g->client);
809 CRStateBits *sb = GetCurrentBits();
810 CRTextureBits *tb = &(sb->texture);
811 CRTextureUnit *unit = t->unit + t->curTextureUnit;
812 CRTextureObj *tobj = unit->currentTexture1D;
813 CRTextureLevel *tl = tobj->level[0] + level;
814
815 FLUSH();
816
817 if (ErrorCheckTexSubImage(1, target, level, xoffset, 0, 0,
818 width, 1, 1)) {
819 return; /* GL error state already set */
820 }
821
822 xoffset += tl->border;
823
824 crPixelCopy1D((void *) (tl->img + xoffset * tl->bytesPerPixel),
825 tl->format, tl->type,
826 pixels, format, type, width, &(c->unpack));
827
828#ifdef CR_SGIS_generate_mipmap
829 if (level == tobj->baseLevel && tobj->generateMipmap) {
830 generate_mipmap(tobj, target);
831 }
832 else {
833 tl->generateMipmap = GL_FALSE;
834 }
835#endif
836
837 DIRTY(tobj->dirty, g->neg_bitid);
838 DIRTY(tobj->imageBit, g->neg_bitid);
839 DIRTY(tl->dirty, g->neg_bitid);
840 DIRTY(tb->dirty, g->neg_bitid);
841}
842
843
844void STATE_APIENTRY
845crStateTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
846 GLsizei width, GLsizei height,
847 GLenum format, GLenum type, const GLvoid * pixels)
848{
849 CRContext *g = GetCurrentContext();
850 CRClientState *c = &(g->client);
851 CRStateBits *sb = GetCurrentBits();
852 CRTextureBits *tb = &(sb->texture);
853 CRTextureObj *tobj;
854 CRTextureLevel *tl;
855 GLubyte *subimg = NULL;
856 GLubyte *img = NULL;
857 GLubyte *src;
858 int i;
859
860 FLUSH();
861
862 if (ErrorCheckTexSubImage(2, target, level, xoffset, yoffset, 0,
863 width, height, 1)) {
864 return; /* GL error state already set */
865 }
866
867 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
868 CRASSERT(tobj);
869 CRASSERT(tl);
870
871 xoffset += tl->border;
872 yoffset += tl->border;
873
874 subimg =
875 (GLubyte *) crAlloc(crImageSize(tl->format, tl->type, width, height));
876
877 crPixelCopy2D(width, height, subimg, tl->format, tl->type, NULL, /* dst */
878 pixels, format, type, &(c->unpack)); /* src */
879
880 img = tl->img +
881 xoffset * tl->bytesPerPixel + yoffset * tl->width * tl->bytesPerPixel;
882
883 src = subimg;
884
885 /* Copy the data into the texture */
886 for (i = 0; i < height; i++)
887 {
888 crMemcpy(img, src, tl->bytesPerPixel * width);
889 img += tl->width * tl->bytesPerPixel;
890 src += width * tl->bytesPerPixel;
891 }
892
893 crFree(subimg);
894
895#ifdef CR_SGIS_generate_mipmap
896 if (level == tobj->baseLevel && tobj->generateMipmap) {
897 generate_mipmap(tobj, target);
898 }
899 else {
900 tl->generateMipmap = GL_FALSE;
901 }
902#endif
903
904 DIRTY(tobj->dirty, g->neg_bitid);
905 DIRTY(tobj->imageBit, g->neg_bitid);
906 DIRTY(tl->dirty, g->neg_bitid);
907 DIRTY(tb->dirty, g->neg_bitid);
908}
909
910#if defined( CR_OPENGL_VERSION_1_2 )
911void STATE_APIENTRY
912crStateTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
913 GLint zoffset, GLsizei width, GLsizei height,
914 GLsizei depth, GLenum format, GLenum type,
915 const GLvoid * pixels)
916{
917 CRContext *g = GetCurrentContext();
918 CRTextureState *t = &(g->texture);
919 CRClientState *c = &(g->client);
920 CRStateBits *sb = GetCurrentBits();
921 CRTextureBits *tb = &(sb->texture);
922 CRTextureUnit *unit = t->unit + t->curTextureUnit;
923 CRTextureObj *tobj = unit->currentTexture3D;
924 CRTextureLevel *tl = tobj->level[0] + level;
925 GLubyte *subimg = NULL;
926 GLubyte *img = NULL;
927 GLubyte *src;
928 int i;
929
930 FLUSH();
931
932 if (ErrorCheckTexSubImage(3, target, level, xoffset, yoffset, zoffset,
933 width, height, depth)) {
934 return; /* GL error state already set */
935 }
936
937 xoffset += tl->border;
938 yoffset += tl->border;
939 zoffset += tl->border;
940
941 subimg =
942 (GLubyte *)
943 crAlloc(crTextureSize(tl->format, tl->type, width, height, depth));
944
945 crPixelCopy3D(width, height, depth, subimg, tl->format, tl->type, NULL,
946 pixels, format, type, &(c->unpack));
947
948 img = tl->img + xoffset * tl->bytesPerPixel +
949 yoffset * tl->width * tl->bytesPerPixel +
950 zoffset * tl->width * tl->height * tl->bytesPerPixel;
951
952 src = subimg;
953
954 /* Copy the data into the texture */
955 for (i = 0; i < depth; i++)
956 {
957 crMemcpy(img, src, tl->bytesPerPixel * width * height);
958 img += tl->width * tl->height * tl->bytesPerPixel;
959 src += width * height * tl->bytesPerPixel;
960 }
961
962 crFree(subimg);
963
964#ifdef CR_SGIS_generate_mipmap
965 if (level == tobj->baseLevel && tobj->generateMipmap) {
966 generate_mipmap(tobj, target);
967 }
968 else {
969 tl->generateMipmap = GL_FALSE;
970 }
971#endif
972
973 DIRTY(tobj->dirty, g->neg_bitid);
974 DIRTY(tobj->imageBit, g->neg_bitid);
975 DIRTY(tl->dirty, g->neg_bitid);
976 DIRTY(tb->dirty, g->neg_bitid);
977}
978#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
979
980
981void STATE_APIENTRY
982crStateCompressedTexImage1DARB(GLenum target, GLint level,
983 GLenum internalFormat, GLsizei width,
984 GLint border, GLsizei imageSize,
985 const GLvoid * data)
986{
987 CRContext *g = GetCurrentContext();
988 CRTextureState *t = &(g->texture);
989 CRTextureObj *tobj;
990 CRTextureLevel *tl;
991 CRStateBits *sb = GetCurrentBits();
992 CRTextureBits *tb = &(sb->texture);
993
994 FLUSH();
995
996 if (ErrorCheckTexImage(1, target, level, width, 1, 1, border)) {
997 if (IsProxyTarget(target)) {
998 /* clear all state, but don't generate error */
999 crStateTextureInitTextureObj(g, &(t->proxy1D), 0, GL_TEXTURE_1D);
1000 }
1001 else {
1002 /* error was already recorded */
1003 }
1004 return;
1005 }
1006
1007 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1008 CRASSERT(tobj);
1009 CRASSERT(tl);
1010
1011 if (IsProxyTarget(target))
1012 tl->bytes = 0;
1013 else
1014 tl->bytes = imageSize;
1015
1016 if (tl->bytes)
1017 {
1018 /* this is not a proxy texture target so alloc storage */
1019 if (tl->img)
1020 crFree(tl->img);
1021 tl->img = (GLubyte *) crAlloc(tl->bytes);
1022 if (!tl->img)
1023 {
1024 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1025 "glTexImage1D out of memory");
1026 return;
1027 }
1028 if (data)
1029 crMemcpy(tl->img, data, imageSize);
1030 }
1031
1032 tl->width = width;
1033 tl->height = 1;
1034 tl->depth = 1;
1035 tl->border = border;
1036 tl->format = GL_NONE;
1037 tl->type = GL_NONE;
1038 tl->internalFormat = internalFormat;
1039 crStateTextureInitTextureFormat(tl, internalFormat);
1040 tl->compressed = GL_TRUE;
1041 tl->bytesPerPixel = 0; /* n/a */
1042
1043#ifdef CR_SGIS_generate_mipmap
1044 if (level == tobj->baseLevel && tobj->generateMipmap) {
1045 generate_mipmap(tobj, target);
1046 }
1047 else {
1048 tl->generateMipmap = GL_FALSE;
1049 }
1050#endif
1051
1052 DIRTY(tobj->dirty, g->neg_bitid);
1053 DIRTY(tobj->imageBit, g->neg_bitid);
1054 DIRTY(tl->dirty, g->neg_bitid);
1055 DIRTY(tb->dirty, g->neg_bitid);
1056}
1057
1058
1059void STATE_APIENTRY
1060crStateCompressedTexImage2DARB(GLenum target, GLint level,
1061 GLenum internalFormat, GLsizei width,
1062 GLsizei height, GLint border,
1063 GLsizei imageSize, const GLvoid * data)
1064{
1065 CRContext *g = GetCurrentContext();
1066 CRTextureState *t = &(g->texture);
1067 CRTextureObj *tobj = NULL;
1068 CRTextureLevel *tl = NULL;
1069 CRStateBits *sb = GetCurrentBits();
1070 CRTextureBits *tb = &(sb->texture);
1071
1072 FLUSH();
1073
1074 if (ErrorCheckTexImage(2, target, level, width, height, 1, border)) {
1075 if (IsProxyTarget(target)) {
1076 /* clear all state, but don't generate error */
1077 crStateTextureInitTextureObj(g, &(t->proxy2D), 0, GL_TEXTURE_2D);
1078 }
1079 else {
1080 /* error was already recorded */
1081 }
1082 return;
1083 }
1084
1085 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1086 CRASSERT(tobj);
1087 CRASSERT(tl);
1088
1089 if (IsProxyTarget(target))
1090 tl->bytes = 0;
1091 else
1092 tl->bytes = imageSize;
1093
1094 if (tl->bytes)
1095 {
1096 /* this is not a proxy texture target so alloc storage */
1097 if (tl->img)
1098 crFree(tl->img);
1099 tl->img = (GLubyte *) crAlloc(tl->bytes);
1100 if (!tl->img)
1101 {
1102 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1103 "glTexImage2D out of memory");
1104 return;
1105 }
1106 if (data)
1107 crMemcpy(tl->img, data, imageSize);
1108 }
1109
1110 tl->width = width;
1111 tl->height = height;
1112 tl->depth = 1;
1113 tl->border = border;
1114 tl->format = GL_NONE;
1115 tl->type = GL_NONE;
1116 tl->internalFormat = internalFormat;
1117 crStateTextureInitTextureFormat(tl, internalFormat);
1118 tl->compressed = GL_TRUE;
1119 tl->bytesPerPixel = 0; /* n/a */
1120
1121#ifdef CR_SGIS_generate_mipmap
1122 if (level == tobj->baseLevel && tobj->generateMipmap) {
1123 generate_mipmap(tobj, target);
1124 }
1125 else {
1126 tl->generateMipmap = GL_FALSE;
1127 }
1128#endif
1129
1130 /* XXX may need to do some fine-tuning here for proxy textures */
1131 DIRTY(tobj->dirty, g->neg_bitid);
1132 DIRTY(tobj->imageBit, g->neg_bitid);
1133 DIRTY(tl->dirty, g->neg_bitid);
1134 DIRTY(tb->dirty, g->neg_bitid);
1135}
1136
1137
1138void STATE_APIENTRY
1139crStateCompressedTexImage3DARB(GLenum target, GLint level,
1140 GLenum internalFormat, GLsizei width,
1141 GLsizei height, GLsizei depth, GLint border,
1142 GLsizei imageSize, const GLvoid * data)
1143{
1144 CRContext *g = GetCurrentContext();
1145 CRTextureState *t = &(g->texture);
1146 CRTextureObj *tobj = NULL;
1147 CRTextureLevel *tl = NULL;
1148 CRStateBits *sb = GetCurrentBits();
1149 CRTextureBits *tb = &(sb->texture);
1150
1151 FLUSH();
1152
1153 if (ErrorCheckTexImage(3, target, level, width, height, depth, border)) {
1154 if (IsProxyTarget(target)) {
1155 /* clear all state, but don't generate error */
1156 crStateTextureInitTextureObj(g, &(t->proxy3D), 0, GL_TEXTURE_3D);
1157 }
1158 else {
1159 /* error was already recorded */
1160 }
1161 return;
1162 }
1163
1164 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1165 CRASSERT(tobj);
1166 CRASSERT(tl);
1167
1168 if (IsProxyTarget(target))
1169 tl->bytes = 0;
1170 else
1171 tl->bytes = imageSize;
1172
1173 if (tl->bytes)
1174 {
1175 /* this is not a proxy texture target so alloc storage */
1176 if (tl->img)
1177 crFree(tl->img);
1178 tl->img = (GLubyte *) crAlloc(tl->bytes);
1179 if (!tl->img)
1180 {
1181 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1182 "glCompressedTexImage3D out of memory");
1183 return;
1184 }
1185 if (data)
1186 crMemcpy(tl->img, data, imageSize);
1187 }
1188
1189 tl->width = width;
1190 tl->height = height;
1191 tl->depth = depth;
1192 tl->border = border;
1193 tl->format = GL_NONE;
1194 tl->type = GL_NONE;
1195 tl->internalFormat = internalFormat;
1196 crStateTextureInitTextureFormat(tl, internalFormat);
1197 tl->compressed = GL_TRUE;
1198 tl->bytesPerPixel = 0; /* n/a */
1199
1200#ifdef CR_SGIS_generate_mipmap
1201 if (level == tobj->baseLevel && tobj->generateMipmap) {
1202 generate_mipmap(tobj, target);
1203 }
1204 else {
1205 tl->generateMipmap = GL_FALSE;
1206 }
1207#endif
1208
1209 /* XXX may need to do some fine-tuning here for proxy textures */
1210 DIRTY(tobj->dirty, g->neg_bitid);
1211 DIRTY(tobj->imageBit, g->neg_bitid);
1212 DIRTY(tl->dirty, g->neg_bitid);
1213 DIRTY(tb->dirty, g->neg_bitid);
1214}
1215
1216
1217void STATE_APIENTRY
1218crStateCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
1219 GLsizei width, GLenum format,
1220 GLsizei imageSize, const GLvoid * data)
1221{
1222 CRContext *g = GetCurrentContext();
1223 CRTextureState *t = &(g->texture);
1224 CRStateBits *sb = GetCurrentBits();
1225 CRTextureBits *tb = &(sb->texture);
1226 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1227 CRTextureObj *tobj = unit->currentTexture1D;
1228 CRTextureLevel *tl = tobj->level[0] + level;
1229
1230 FLUSH();
1231
1232 if (ErrorCheckTexSubImage(1, target, level, xoffset, 0, 0, width, 1, 1)) {
1233 return; /* GL error state already set */
1234 }
1235
1236 xoffset += tl->border;
1237
1238 if (xoffset == 0 && width == tl->width) {
1239 /* just memcpy */
1240 crMemcpy(tl->img, data, imageSize);
1241 }
1242 else {
1243 /* XXX this depends on the exact compression method */
1244 }
1245
1246#ifdef CR_SGIS_generate_mipmap
1247 if (level == tobj->baseLevel && tobj->generateMipmap) {
1248 generate_mipmap(tobj, target);
1249 }
1250 else {
1251 tl->generateMipmap = GL_FALSE;
1252 }
1253#endif
1254
1255 DIRTY(tobj->dirty, g->neg_bitid);
1256 DIRTY(tobj->imageBit, g->neg_bitid);
1257 DIRTY(tl->dirty, g->neg_bitid);
1258 DIRTY(tb->dirty, g->neg_bitid);
1259}
1260
1261
1262void STATE_APIENTRY
1263crStateCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
1264 GLint yoffset, GLsizei width,
1265 GLsizei height, GLenum format,
1266 GLsizei imageSize, const GLvoid * data)
1267{
1268 CRContext *g = GetCurrentContext();
1269 CRTextureState *t = &(g->texture);
1270 CRStateBits *sb = GetCurrentBits();
1271 CRTextureBits *tb = &(sb->texture);
1272 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1273 CRTextureObj *tobj = unit->currentTexture1D;
1274 CRTextureLevel *tl = tobj->level[0] + level;
1275
1276 FLUSH();
1277
1278 if (ErrorCheckTexSubImage(2, target, level, xoffset, yoffset, 0,
1279 width, height, 1)) {
1280 return; /* GL error state already set */
1281 }
1282
1283 xoffset += tl->border;
1284 yoffset += tl->border;
1285
1286 if (xoffset == 0 && width == tl->width &&
1287 yoffset == 0 && height == tl->height) {
1288 /* just memcpy */
1289 crMemcpy(tl->img, data, imageSize);
1290 }
1291 else {
1292 /* XXX this depends on the exact compression method */
1293 }
1294
1295#ifdef CR_SGIS_generate_mipmap
1296 if (level == tobj->baseLevel && tobj->generateMipmap) {
1297 generate_mipmap(tobj, target);
1298 }
1299 else {
1300 tl->generateMipmap = GL_FALSE;
1301 }
1302#endif
1303
1304 DIRTY(tobj->dirty, g->neg_bitid);
1305 DIRTY(tobj->imageBit, g->neg_bitid);
1306 DIRTY(tl->dirty, g->neg_bitid);
1307 DIRTY(tb->dirty, g->neg_bitid);
1308}
1309
1310
1311void STATE_APIENTRY
1312crStateCompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
1313 GLint yoffset, GLint zoffset, GLsizei width,
1314 GLsizei height, GLsizei depth,
1315 GLenum format, GLsizei imageSize,
1316 const GLvoid * data)
1317{
1318 CRContext *g = GetCurrentContext();
1319 CRTextureState *t = &(g->texture);
1320 CRStateBits *sb = GetCurrentBits();
1321 CRTextureBits *tb = &(sb->texture);
1322 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1323 CRTextureObj *tobj = unit->currentTexture1D;
1324 CRTextureLevel *tl = tobj->level[0] + level;
1325
1326 FLUSH();
1327
1328 if (ErrorCheckTexSubImage(3, target, level, xoffset, yoffset, zoffset,
1329 width, height, depth)) {
1330 return; /* GL error state already set */
1331 }
1332
1333 xoffset += tl->border;
1334 yoffset += tl->border;
1335 zoffset += tl->border;
1336
1337 if (xoffset == 0 && width == tl->width &&
1338 yoffset == 0 && height == tl->height &&
1339 zoffset == 0 && depth == tl->depth) {
1340 /* just memcpy */
1341 crMemcpy(tl->img, data, imageSize);
1342 }
1343 else {
1344 /* XXX this depends on the exact compression method */
1345 }
1346
1347#ifdef CR_SGIS_generate_mipmap
1348 if (level == tobj->baseLevel && tobj->generateMipmap) {
1349 generate_mipmap(tobj, target);
1350 }
1351 else {
1352 tl->generateMipmap = GL_FALSE;
1353 }
1354#endif
1355
1356 DIRTY(tobj->dirty, g->neg_bitid);
1357 DIRTY(tobj->imageBit, g->neg_bitid);
1358 DIRTY(tl->dirty, g->neg_bitid);
1359 DIRTY(tb->dirty, g->neg_bitid);
1360}
1361
1362
1363void STATE_APIENTRY
1364crStateGetCompressedTexImageARB(GLenum target, GLint level, GLvoid * img)
1365{
1366 CRContext *g = GetCurrentContext();
1367 CRTextureObj *tobj;
1368 CRTextureLevel *tl;
1369
1370 if (g->current.inBeginEnd)
1371 {
1372 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1373 "glGetCompressedTexImage called in begin/end");
1374 return;
1375 }
1376
1377 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1378 if (!tobj || !tl) {
1379 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1380 "glGetCompressedTexImage(invalid target or level)");
1381 return;
1382 }
1383
1384 if (!tl->compressed) {
1385 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1386 "glGetCompressedTexImage(not a compressed texture)");
1387 return;
1388 }
1389
1390 crMemcpy(img, tl->img, tl->bytes);
1391}
1392
1393
1394void STATE_APIENTRY
1395crStateGetTexImage(GLenum target, GLint level, GLenum format,
1396 GLenum type, GLvoid * pixels)
1397{
1398 CRContext *g = GetCurrentContext();
1399 CRClientState *c = &(g->client);
1400 CRTextureObj *tobj;
1401 CRTextureLevel *tl;
1402
1403 if (g->current.inBeginEnd)
1404 {
1405 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1406 "glGetTexImage called in begin/end");
1407 return;
1408 }
1409
1410 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1411 if (!tobj || !tl) {
1412 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1413 "glGetTexImage(invalid target or level)");
1414 return;
1415 }
1416
1417 if (tl->compressed) {
1418 crWarning("glGetTexImage cannot decompress a compressed texture!");
1419 return;
1420 }
1421
1422 switch (format)
1423 {
1424 case GL_RED:
1425 case GL_GREEN:
1426 case GL_BLUE:
1427 case GL_ALPHA:
1428 case GL_RGB:
1429 case GL_RGBA:
1430 case GL_LUMINANCE:
1431 case GL_LUMINANCE_ALPHA:
1432 break;
1433 default:
1434 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1435 "glGetTexImage called with bogus format: %d", format);
1436 return;
1437 }
1438
1439 switch (type)
1440 {
1441 case GL_UNSIGNED_BYTE:
1442 case GL_BYTE:
1443 case GL_UNSIGNED_SHORT:
1444 case GL_SHORT:
1445 case GL_UNSIGNED_INT:
1446 case GL_INT:
1447 case GL_FLOAT:
1448 break;
1449 default:
1450 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1451 "glGetTexImage called with bogus type: %d", type);
1452 return;
1453 }
1454
1455#ifdef CR_OPENGL_VERSION_1_2
1456 if (target == GL_TEXTURE_3D)
1457 {
1458 crPixelCopy3D(tl->width, tl->height, tl->depth, (GLvoid *) pixels, format,
1459 type, NULL, (tl->img), format, type, &(c->pack));
1460 }
1461 else
1462#endif
1463 if ((target == GL_TEXTURE_2D) || (target == GL_TEXTURE_1D))
1464 {
1465 crPixelCopy2D(tl->width, tl->height, (GLvoid *) pixels, format, type, NULL, /* dst */
1466 (tl->img), format, type, &(c->pack)); /* src */
1467 }
1468}
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