summaryrefslogtreecommitdiffstats
path: root/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c')
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c3418
1 files changed, 3418 insertions, 0 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
new file mode 100644
index 00000000..5184feb6
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_texture.c
@@ -0,0 +1,3418 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "state.h"
+#include "state/cr_statetypes.h"
+#include "state/cr_texture.h"
+#include "cr_hash.h"
+#include "cr_string.h"
+#include "cr_mem.h"
+#include "cr_version.h"
+#include "state_internals.h"
+
+#ifdef DEBUG_misha
+#include <iprt/assert.h>
+#endif
+
+#define UNUSED(x) ((void) (x))
+
+#define GET_TOBJ(tobj, state, id) \
+ tobj = (CRTextureObj *) crHashtableSearch(g->shared->textureTable, id);
+
+
+void crStateTextureDestroy(CRContext *ctx)
+{
+ crStateDeleteTextureObjectData(&ctx->texture.base1D);
+ crStateDeleteTextureObjectData(&ctx->texture.proxy1D);
+ crStateDeleteTextureObjectData(&ctx->texture.base2D);
+ crStateDeleteTextureObjectData(&ctx->texture.proxy2D);
+#ifdef CR_OPENGL_VERSION_1_2
+ crStateDeleteTextureObjectData(&ctx->texture.base3D);
+ crStateDeleteTextureObjectData(&ctx->texture.proxy3D);
+#endif
+#ifdef CR_ARB_texture_cube_map
+ crStateDeleteTextureObjectData(&ctx->texture.baseCubeMap);
+ crStateDeleteTextureObjectData(&ctx->texture.proxyCubeMap);
+#endif
+#ifdef CR_NV_texture_rectangle
+ crStateDeleteTextureObjectData(&ctx->texture.baseRect);
+ crStateDeleteTextureObjectData(&ctx->texture.proxyRect);
+#endif
+}
+
+
+void crStateTextureInit(CRContext *ctx)
+{
+ CRLimitsState *limits = &ctx->limits;
+ CRTextureState *t = &ctx->texture;
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+ unsigned int i;
+ unsigned int a;
+ GLvectorf zero_vector = {0.0f, 0.0f, 0.0f, 0.0f};
+ GLcolorf zero_color = {0.0f, 0.0f, 0.0f, 0.0f};
+ GLvectorf x_vector = {1.0f, 0.0f, 0.0f, 0.0f};
+ GLvectorf y_vector = {0.0f, 1.0f, 0.0f, 0.0f};
+
+ /* compute max levels from max sizes */
+ for (i=0, a=limits->maxTextureSize; a; i++, a=a>>1);
+ t->maxLevel = i-1;
+ for (i=0, a=limits->max3DTextureSize; a; i++, a=a>>1);
+ t->max3DLevel = i-1;
+#ifdef CR_ARB_texture_cube_map
+ for (i=0, a=limits->maxCubeMapTextureSize; a; i++, a=a>>1);
+ t->maxCubeMapLevel = i-1;
+#endif
+#ifdef CR_NV_texture_rectangle
+ for (i=0, a=limits->maxRectTextureSize; a; i++, a=a>>1);
+ t->maxRectLevel = i-1;
+#endif
+
+ crStateTextureInitTextureObj(ctx, &(t->base1D), 0, GL_TEXTURE_1D);
+ crStateTextureInitTextureObj(ctx, &(t->base2D), 0, GL_TEXTURE_2D);
+#ifdef CR_OPENGL_VERSION_1_2
+ crStateTextureInitTextureObj(ctx, &(t->base3D), 0, GL_TEXTURE_3D);
+#endif
+#ifdef CR_ARB_texture_cube_map
+ crStateTextureInitTextureObj(ctx, &(t->baseCubeMap), 0,
+ GL_TEXTURE_CUBE_MAP_ARB);
+#endif
+#ifdef CR_NV_texture_rectangle
+ crStateTextureInitTextureObj(ctx, &(t->baseRect), 0,
+ GL_TEXTURE_RECTANGLE_NV);
+#endif
+
+ crStateTextureInitTextureObj(ctx, &(t->proxy1D), 0, GL_TEXTURE_1D);
+ crStateTextureInitTextureObj(ctx, &(t->proxy2D), 0, GL_TEXTURE_2D);
+#ifdef CR_OPENGL_VERSION_1_2
+ crStateTextureInitTextureObj(ctx, &(t->proxy3D), 0, GL_TEXTURE_3D);
+#endif
+#ifdef CR_ARB_texture_cube_map
+ crStateTextureInitTextureObj(ctx, &(t->proxyCubeMap), 0,
+ GL_TEXTURE_CUBE_MAP_ARB);
+#endif
+#ifdef CR_NV_texture_rectangle
+ crStateTextureInitTextureObj(ctx, &(t->proxyRect), 0,
+ GL_TEXTURE_RECTANGLE_NV);
+#endif
+
+ t->curTextureUnit = 0;
+
+ /* Per-unit initialization */
+ for (i = 0; i < limits->maxTextureUnits; i++)
+ {
+ t->unit[i].currentTexture1D = &(t->base1D);
+ t->unit[i].currentTexture2D = &(t->base2D);
+ t->unit[i].currentTexture3D = &(t->base3D);
+#ifdef CR_ARB_texture_cube_map
+ t->unit[i].currentTextureCubeMap = &(t->baseCubeMap);
+#endif
+#ifdef CR_NV_texture_rectangle
+ t->unit[i].currentTextureRect = &(t->baseRect);
+#endif
+
+ t->unit[i].enabled1D = GL_FALSE;
+ t->unit[i].enabled2D = GL_FALSE;
+ t->unit[i].enabled3D = GL_FALSE;
+ t->unit[i].enabledCubeMap = GL_FALSE;
+#ifdef CR_NV_texture_rectangle
+ t->unit[i].enabledRect = GL_FALSE;
+#endif
+ t->unit[i].textureGen.s = GL_FALSE;
+ t->unit[i].textureGen.t = GL_FALSE;
+ t->unit[i].textureGen.r = GL_FALSE;
+ t->unit[i].textureGen.q = GL_FALSE;
+
+ t->unit[i].gen.s = GL_EYE_LINEAR;
+ t->unit[i].gen.t = GL_EYE_LINEAR;
+ t->unit[i].gen.r = GL_EYE_LINEAR;
+ t->unit[i].gen.q = GL_EYE_LINEAR;
+
+ t->unit[i].objSCoeff = x_vector;
+ t->unit[i].objTCoeff = y_vector;
+ t->unit[i].objRCoeff = zero_vector;
+ t->unit[i].objQCoeff = zero_vector;
+
+ t->unit[i].eyeSCoeff = x_vector;
+ t->unit[i].eyeTCoeff = y_vector;
+ t->unit[i].eyeRCoeff = zero_vector;
+ t->unit[i].eyeQCoeff = zero_vector;
+ t->unit[i].envMode = GL_MODULATE;
+ t->unit[i].envColor = zero_color;
+
+ t->unit[i].combineModeRGB = GL_MODULATE;
+ t->unit[i].combineModeA = GL_MODULATE;
+ t->unit[i].combineSourceRGB[0] = GL_TEXTURE;
+ t->unit[i].combineSourceRGB[1] = GL_PREVIOUS_EXT;
+ t->unit[i].combineSourceRGB[2] = GL_CONSTANT_EXT;
+ t->unit[i].combineSourceA[0] = GL_TEXTURE;
+ t->unit[i].combineSourceA[1] = GL_PREVIOUS_EXT;
+ t->unit[i].combineSourceA[2] = GL_CONSTANT_EXT;
+ t->unit[i].combineOperandRGB[0] = GL_SRC_COLOR;
+ t->unit[i].combineOperandRGB[1] = GL_SRC_COLOR;
+ t->unit[i].combineOperandRGB[2] = GL_SRC_ALPHA;
+ t->unit[i].combineOperandA[0] = GL_SRC_ALPHA;
+ t->unit[i].combineOperandA[1] = GL_SRC_ALPHA;
+ t->unit[i].combineOperandA[2] = GL_SRC_ALPHA;
+ t->unit[i].combineScaleRGB = 1.0F;
+ t->unit[i].combineScaleA = 1.0F;
+#ifdef CR_EXT_texture_lod_bias
+ t->unit[i].lodBias = 0.0F;
+#endif
+ RESET(tb->enable[i], ctx->bitid);
+ RESET(tb->current[i], ctx->bitid);
+ RESET(tb->objGen[i], ctx->bitid);
+ RESET(tb->eyeGen[i], ctx->bitid);
+ RESET(tb->genMode[i], ctx->bitid);
+ RESET(tb->envBit[i], ctx->bitid);
+ }
+ RESET(tb->dirty, ctx->bitid);
+}
+
+
+void
+crStateTextureInitTextureObj(CRContext *ctx, CRTextureObj *tobj,
+ GLuint name, GLenum target)
+{
+ const CRTextureState *t = &(ctx->texture);
+ int i, face;
+
+ tobj->borderColor.r = 0.0f;
+ tobj->borderColor.g = 0.0f;
+ tobj->borderColor.b = 0.0f;
+ tobj->borderColor.a = 0.0f;
+ tobj->minFilter = GL_NEAREST_MIPMAP_LINEAR;
+ tobj->magFilter = GL_LINEAR;
+ tobj->wrapS = GL_REPEAT;
+ tobj->wrapT = GL_REPEAT;
+#ifdef CR_OPENGL_VERSION_1_2
+ tobj->wrapR = GL_REPEAT;
+ tobj->priority = 1.0f;
+ tobj->minLod = -1000.0;
+ tobj->maxLod = 1000.0;
+ tobj->baseLevel = 0;
+ tobj->maxLevel = t->maxLevel;
+#endif
+ tobj->target = target;
+ tobj->id = name;
+ tobj->hwid = 0;
+
+#ifndef IN_GUEST
+ crStateGetTextureObjHWID(tobj);
+#endif
+
+ CRASSERT(t->maxLevel);
+
+ /* XXX don't always need all six faces */
+ for (face = 0; face < 6; face++) {
+ /* allocate array of mipmap levels */
+ CRASSERT(t->maxLevel < CR_MAX_MIPMAP_LEVELS);
+ tobj->level[face] = (CRTextureLevel *)
+ crCalloc(sizeof(CRTextureLevel) * CR_MAX_MIPMAP_LEVELS);
+
+ if (!tobj->level[face])
+ return; /* out of memory */
+
+ /* init non-zero fields */
+ for (i = 0; i <= t->maxLevel; i++) {
+ CRTextureLevel *tl = &(tobj->level[face][i]);
+ tl->internalFormat = GL_ONE;
+ tl->format = GL_RGBA;
+ tl->type = GL_UNSIGNED_BYTE;
+ crStateTextureInitTextureFormat( tl, tl->internalFormat );
+ }
+ }
+
+#ifdef CR_EXT_texture_filter_anisotropic
+ tobj->maxAnisotropy = 1.0f;
+#endif
+
+#ifdef CR_ARB_depth_texture
+ tobj->depthMode = GL_LUMINANCE;
+#endif
+
+#ifdef CR_ARB_shadow
+ tobj->compareMode = GL_NONE;
+ tobj->compareFunc = GL_LEQUAL;
+#endif
+
+#ifdef CR_ARB_shadow_ambient
+ tobj->compareFailValue = 0.0;
+#endif
+
+ RESET(tobj->dirty, ctx->bitid);
+ RESET(tobj->imageBit, ctx->bitid);
+ for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
+ {
+ RESET(tobj->paramsBit[i], ctx->bitid);
+ }
+
+ CR_STATE_SHAREDOBJ_USAGE_INIT(tobj);
+ CR_STATE_SHAREDOBJ_USAGE_SET(tobj, ctx);
+}
+
+
+/* ================================================================
+ * Texture internal formats:
+ */
+
+const CRTextureFormat _texformat_rgba8888 = {
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_argb8888 = {
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_rgb888 = {
+ 8, /* RedBits */
+ 8, /* GreenBits */
+ 8, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_rgb565 = {
+ 5, /* RedBits */
+ 6, /* GreenBits */
+ 5, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_argb4444 = {
+ 4, /* RedBits */
+ 4, /* GreenBits */
+ 4, /* BlueBits */
+ 4, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_argb1555 = {
+ 5, /* RedBits */
+ 5, /* GreenBits */
+ 5, /* BlueBits */
+ 1, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_al88 = {
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_rgb332 = {
+ 3, /* RedBits */
+ 3, /* GreenBits */
+ 2, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_a8 = {
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 8, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_l8 = {
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 8, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_i8 = {
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 8, /* IntensityBits */
+ 0, /* IndexBits */
+};
+
+const CRTextureFormat _texformat_ci8 = {
+ 0, /* RedBits */
+ 0, /* GreenBits */
+ 0, /* BlueBits */
+ 0, /* AlphaBits */
+ 0, /* LuminanceBits */
+ 0, /* IntensityBits */
+ 8, /* IndexBits */
+};
+
+
+/**
+ * Given an internal texture format enum or 1, 2, 3, 4 initialize the
+ * texture levels texture format. This basically just indicates the
+ * number of red, green, blue, alpha, luminance, etc. bits are used to
+ * store the image.
+ */
+void
+crStateTextureInitTextureFormat( CRTextureLevel *tl, GLenum internalFormat )
+{
+ switch (internalFormat) {
+ case 4:
+ case GL_RGBA:
+ case GL_COMPRESSED_RGBA_ARB:
+#ifdef CR_EXT_texture_sRGB
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+#endif
+ tl->texFormat = &_texformat_rgba8888;
+ break;
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB_ARB:
+#ifdef CR_EXT_texture_sRGB
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+#endif
+ tl->texFormat = &_texformat_rgb888;
+ break;
+
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ tl->texFormat = &_texformat_rgba8888;
+ break;
+
+ case GL_R3_G3_B2:
+ tl->texFormat = &_texformat_rgb332;
+ break;
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ tl->texFormat = &_texformat_rgb888;
+ break;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case GL_COMPRESSED_ALPHA_ARB:
+ tl->texFormat = &_texformat_a8;
+ break;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case GL_COMPRESSED_LUMINANCE_ARB:
+#ifdef CR_EXT_texture_sRGB
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+#endif
+ tl->texFormat = &_texformat_l8;
+ break;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
+#ifdef CR_EXT_texture_sRGB
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif
+ tl->texFormat = &_texformat_al88;
+ break;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case GL_COMPRESSED_INTENSITY_ARB:
+ tl->texFormat = &_texformat_i8;
+ break;
+
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ tl->texFormat = &_texformat_ci8;
+ break;
+
+ default:
+ return;
+ }
+}
+
+#if 0
+void crStateTextureInitTexture (GLuint name)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTextureObj *tobj;
+
+ GET_TOBJ(tobj, name);
+ if (!tobj) return;
+
+ crStateTextureInitTextureObj(g, tobj, name, GL_NONE);
+}
+#endif
+
+
+
+/**
+ * Return the texture object corresponding to the given target and ID.
+ */
+CRTextureObj *
+crStateTextureGet(GLenum target, GLuint name)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTextureObj *tobj;
+
+ if (name == 0)
+ {
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return &t->base1D;
+ case GL_TEXTURE_2D:
+ return &t->base2D;
+ case GL_TEXTURE_3D:
+ return &t->base3D;
+#ifdef CR_ARB_texture_cube_map
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ return &t->baseCubeMap;
+#endif
+#ifdef CR_NV_texture_rectangle
+ case GL_TEXTURE_RECTANGLE_NV:
+ return &t->baseRect;
+#endif
+ default:
+ return NULL;
+ }
+ }
+
+ GET_TOBJ(tobj, g, name);
+
+ return tobj;
+}
+
+
+/*
+ * Allocate a new texture object with the given name.
+ * Also insert into hash table.
+ */
+static CRTextureObj *
+crStateTextureAllocate_t(CRContext *ctx, GLuint name)
+{
+ CRTextureObj *tobj;
+
+ if (!name)
+ return NULL;
+
+ tobj = crCalloc(sizeof(CRTextureObj));
+ if (!tobj)
+ return NULL;
+
+ crHashtableAdd( ctx->shared->textureTable, name, (void *) tobj );
+
+ crStateTextureInitTextureObj(ctx, tobj, name, GL_NONE);
+
+ return tobj;
+}
+
+
+/**
+ * Delete all the data that hangs off a CRTextureObj, but don't
+ * delete the texture object itself, since it may not have been
+ * dynamically allocated.
+ */
+void
+crStateDeleteTextureObjectData(CRTextureObj *tobj)
+{
+ int k;
+ int face;
+
+ CRASSERT(tobj);
+
+ /* Free the texture images */
+ for (face = 0; face < 6; face++) {
+ CRTextureLevel *levels = NULL;
+ levels = tobj->level[face];
+ if (levels) {
+ /* free all mipmap levels for this face */
+ for (k = 0; k < CR_MAX_MIPMAP_LEVELS; k++) {
+ CRTextureLevel *tl = levels + k;
+ if (tl->img) {
+ crFree(tl->img);
+ tl->img = NULL;
+ tl->bytes = 0;
+ }
+ }
+ crFree(levels);
+ }
+ tobj->level[face] = NULL;
+ }
+}
+
+
+void
+crStateDeleteTextureObject(CRTextureObj *tobj)
+{
+ crStateDeleteTextureObjectData(tobj);
+ crFree(tobj);
+}
+
+void crStateRegNames(CRContext *g, CRHashTable *table, GLsizei n, GLuint *names)
+{
+ GLint i;
+ (void)g;
+ for (i = 0; i < n; i++)
+ {
+ if (names[i])
+ {
+ GLboolean isNewKey = crHashtableAllocRegisterKey(table, names[i]);
+ CRASSERT(isNewKey);
+ }
+ else
+ crWarning("RegNames: requested to register a null name");
+ }
+}
+
+void crStateRegTextures(GLsizei n, GLuint *names)
+{
+ CRContext *g = GetCurrentContext();
+ crStateRegNames(g, g->shared->textureTable, n, names);
+}
+
+void crStateGenNames(CRContext *g, CRHashTable *table, GLsizei n, GLuint *names)
+{
+ GLint start;
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "crStateGenNames called in Begin/End");
+ return;
+ }
+
+ if (n < 0)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "Negative n passed to crStateGenNames: %d", n);
+ return;
+ }
+
+ start = crHashtableAllocKeys(table, n);
+ if (start)
+ {
+ GLint i;
+ for (i = 0; i < n; i++)
+ names[i] = (GLuint) (start + i);
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glGenTextures");
+ }
+}
+
+void STATE_APIENTRY crStateGenTextures(GLsizei n, GLuint *textures)
+{
+ CRContext *g = GetCurrentContext();
+ crStateGenNames(g, g->shared->textureTable, n, textures);
+}
+
+static void crStateTextureCheckFBOAPs(GLenum target, GLuint texture)
+{
+ GLuint u;
+ CRFBOAttachmentPoint *ap;
+ CRContext *g = GetCurrentContext();
+ CRFramebufferObjectState *fbo = &g->framebufferobject;
+ CRFramebufferObject *pFBO;
+
+ pFBO = GL_READ_FRAMEBUFFER==target ? fbo->readFB : fbo->drawFB;
+ if (!pFBO) return;
+
+ for (u=0; u<CR_MAX_COLOR_ATTACHMENTS; ++u)
+ {
+ ap = &pFBO->color[u];
+ if (ap->type==GL_TEXTURE && ap->name==texture)
+ {
+ crStateFramebufferTexture1DEXT(target, u+GL_COLOR_ATTACHMENT0_EXT, 0, 0, 0);
+ }
+ }
+
+ ap = &pFBO->depth;
+ if (ap->type==GL_TEXTURE && ap->name==texture)
+ {
+ crStateFramebufferTexture1DEXT(target, GL_DEPTH_ATTACHMENT_EXT, 0, 0, 0);
+ }
+
+ ap = &pFBO->stencil;
+ if (ap->type==GL_TEXTURE && ap->name==texture)
+ {
+ crStateFramebufferTexture1DEXT(target, GL_STENCIL_ATTACHMENT_EXT, 0, 0, 0);
+ }
+}
+
+static void crStateCleanupTextureRefs(CRContext *g, CRTextureObj *tObj)
+{
+ CRTextureState *t = &(g->texture);
+ GLuint u;
+
+ /*
+ ** reset back to the base texture.
+ */
+ for (u = 0; u < g->limits.maxTextureUnits; u++)
+ {
+ if (tObj == t->unit[u].currentTexture1D)
+ {
+ t->unit[u].currentTexture1D = &(t->base1D);
+ }
+ if (tObj == t->unit[u].currentTexture2D)
+ {
+ t->unit[u].currentTexture2D = &(t->base2D);
+ }
+#ifdef CR_OPENGL_VERSION_1_2
+ if (tObj == t->unit[u].currentTexture3D)
+ {
+ t->unit[u].currentTexture3D = &(t->base3D);
+ }
+#endif
+#ifdef CR_ARB_texture_cube_map
+ if (tObj == t->unit[u].currentTextureCubeMap)
+ {
+ t->unit[u].currentTextureCubeMap = &(t->baseCubeMap);
+ }
+#endif
+#ifdef CR_NV_texture_rectangle
+ if (tObj == t->unit[u].currentTextureRect)
+ {
+ t->unit[u].currentTextureRect = &(t->baseRect);
+ }
+#endif
+
+#ifdef CR_EXT_framebuffer_object
+ crStateTextureCheckFBOAPs(GL_DRAW_FRAMEBUFFER, tObj->id);
+ crStateTextureCheckFBOAPs(GL_READ_FRAMEBUFFER, tObj->id);
+#endif
+ }
+}
+
+void STATE_APIENTRY crStateDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+ int i;
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glDeleteTextures called in Begin/End");
+ return;
+ }
+
+ if (n < 0)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "Negative n passed to glDeleteTextures: %d", n);
+ return;
+ }
+
+ for (i=0; i<n; i++)
+ {
+ GLuint name = textures[i];
+ CRTextureObj *tObj;
+ if (!name)
+ continue;
+
+ GET_TOBJ(tObj, g, name);
+ if (tObj)
+ {
+ GLuint j;
+
+ crStateCleanupTextureRefs(g, tObj);
+
+ CR_STATE_SHAREDOBJ_USAGE_CLEAR(tObj, g);
+
+ CR_STATE_SHAREDOBJ_USAGE_FOREACH_USED_IDX(tObj, j)
+ {
+ /* saved state version <= SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS does not have usage bits info,
+ * so on restore, we set mark bits as used.
+ * This is why g_pAvailableContexts[j] could be NULL
+ * also g_pAvailableContexts[0] will hold default context, which we should discard */
+ CRContext *ctx = g_pAvailableContexts[j];
+ if (j && ctx)
+ {
+ crStateCleanupTextureRefs(ctx, tObj);
+ CR_STATE_SHAREDOBJ_USAGE_CLEAR(tObj, g);
+ }
+ else
+ CR_STATE_SHAREDOBJ_USAGE_CLEAR_IDX(tObj, j);
+ }
+
+ /* on the host side, ogl texture object is deleted by a separate cr_server.head_spu->dispatch_table.DeleteTextures(n, newTextures);
+ * in crServerDispatchDeleteTextures, we just delete a state object here, which crStateDeleteTextureObject does */
+ crHashtableDelete(g->shared->textureTable, name, (CRHashtableCallback)crStateDeleteTextureObject);
+ }
+ else
+ {
+ /* call crHashtableDelete in any way, to ensure the allocated key is freed */
+ Assert(crHashtableIsKeyUsed(g->shared->textureTable, name));
+ crHashtableDelete(g->shared->textureTable, name, NULL);
+ }
+ }
+
+ DIRTY(tb->dirty, g->neg_bitid);
+ DIRTY(tb->current[t->curTextureUnit], g->neg_bitid);
+}
+
+
+
+void STATE_APIENTRY crStateClientActiveTextureARB( GLenum texture )
+{
+ CRContext *g = GetCurrentContext();
+ CRClientState *c = &(g->client);
+
+ FLUSH();
+
+ if (!g->extensions.ARB_multitexture) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glClientActiveTextureARB not available");
+ return;
+ }
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glClientActiveTextureARB called in Begin/End");
+ return;
+ }
+
+ if ( texture < GL_TEXTURE0_ARB ||
+ texture >= GL_TEXTURE0_ARB + g->limits.maxTextureUnits)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "crStateClientActiveTexture: unit = %d (max is %d)",
+ texture, g->limits.maxTextureUnits );
+ return;
+ }
+
+ c->curClientTextureUnit = texture - GL_TEXTURE0_ARB;
+
+ DIRTY(GetCurrentBits()->client.dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateActiveTextureARB( GLenum texture )
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ FLUSH();
+
+ if (!g->extensions.ARB_multitexture) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glActiveTextureARB not available");
+ return;
+ }
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glActiveTextureARB called in Begin/End");
+ return;
+ }
+
+ if ( texture < GL_TEXTURE0_ARB || texture >= GL_TEXTURE0_ARB + g->limits.maxTextureUnits)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "Bad texture unit passed to crStateActiveTexture: %d (max is %d)", texture, g->limits.maxTextureUnits );
+ return;
+ }
+
+ t->curTextureUnit = texture - GL_TEXTURE0_ARB;
+
+ /* update the current matrix pointer, etc. */
+ if (g->transform.matrixMode == GL_TEXTURE) {
+ crStateMatrixMode(GL_TEXTURE);
+ }
+}
+
+#ifndef IN_GUEST
+# ifdef DEBUG
+static uint32_t gDbgNumPinned = 0;
+# endif
+
+DECLEXPORT(void) crStatePinTexture(GLuint texture, GLboolean pin)
+{
+ CRTextureObj * pTobj;
+ CRSharedState *pShared = crStateGlobalSharedAcquire();
+ if (pShared)
+ {
+ pTobj = (CRTextureObj*)crHashtableSearch(pShared->textureTable, texture);
+
+ if (pTobj)
+ {
+# ifdef DEBUG
+ if (!pTobj->pinned != !pin)
+ {
+ if (pin)
+ ++gDbgNumPinned;
+ else
+ {
+ Assert(gDbgNumPinned);
+ --gDbgNumPinned;
+ }
+ }
+# endif
+ pTobj->pinned = !!pin;
+ if (!pin)
+ {
+ if (!CR_STATE_SHAREDOBJ_USAGE_IS_USED(pTobj))
+ crStateOnTextureUsageRelease(pShared, pTobj);
+ }
+ }
+ else
+ WARN(("texture %d not defined", texture));
+
+ crStateGlobalSharedRelease();
+ }
+ else
+ WARN(("no global shared"));
+}
+#endif
+
+DECLEXPORT(void) crStateSetTextureUsed(GLuint texture, GLboolean used)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+
+ if (!texture)
+ {
+ crWarning("crStateSetTextureUsed: null texture name specified!");
+ return;
+ }
+
+ GET_TOBJ(tobj, g, texture);
+ if (!tobj)
+ {
+#ifdef IN_GUEST
+ if (used)
+ {
+ tobj = crStateTextureAllocate_t(g, texture);
+ }
+ else
+#endif
+ {
+ WARN(("crStateSetTextureUsed: failed to fined a HW name for texture(%d)!", texture));
+ return;
+ }
+ }
+
+ if (used)
+ CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g);
+ else
+ {
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+ CRTextureState *t = &(g->texture);
+
+ crStateCleanupTextureRefs(g, tobj);
+
+ crStateReleaseTexture(g, tobj);
+
+ DIRTY(tb->dirty, g->neg_bitid);
+ DIRTY(tb->current[t->curTextureUnit], g->neg_bitid);
+ }
+}
+
+void STATE_APIENTRY crStateBindTexture(GLenum target, GLuint texture)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTextureObj *tobj;
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glBindTexture called in Begin/End");
+ return;
+ }
+
+ /* Special Case name = 0 */
+ if (!texture)
+ {
+ switch (target)
+ {
+ case GL_TEXTURE_1D:
+ t->unit[t->curTextureUnit].currentTexture1D = &(t->base1D);
+ break;
+ case GL_TEXTURE_2D:
+ t->unit[t->curTextureUnit].currentTexture2D = &(t->base2D);
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_3D:
+ t->unit[t->curTextureUnit].currentTexture3D = &(t->base3D);
+ break;
+#endif
+#ifdef CR_ARB_texture_cube_map
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ if (!g->extensions.ARB_texture_cube_map) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "Invalid target passed to glBindTexture: %d", target);
+ return;
+ }
+ t->unit[t->curTextureUnit].currentTextureCubeMap = &(t->baseCubeMap);
+ break;
+#endif
+#ifdef CR_NV_texture_rectangle
+ case GL_TEXTURE_RECTANGLE_NV:
+ if (!g->extensions.NV_texture_rectangle) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "Invalid target passed to glBindTexture: %d", target);
+ return;
+ }
+ t->unit[t->curTextureUnit].currentTextureRect = &(t->baseRect);
+ break;
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid target passed to glBindTexture: %d", target);
+ return;
+ }
+
+ DIRTY(tb->dirty, g->neg_bitid);
+ DIRTY(tb->current[t->curTextureUnit], g->neg_bitid);
+ return;
+ }
+
+ /* texture != 0 */
+ /* Get the texture */
+ GET_TOBJ(tobj, g, texture);
+ if (!tobj)
+ {
+ Assert(crHashtableIsKeyUsed(g->shared->textureTable, texture));
+ tobj = crStateTextureAllocate_t(g, texture);
+ }
+
+ CR_STATE_SHAREDOBJ_USAGE_SET(tobj, g);
+
+ /* Check the targets */
+ if (tobj->target == GL_NONE)
+ {
+ /* Target isn't set so set it now.*/
+ tobj->target = target;
+ }
+ else if ((tobj->target != target)
+ && !((target==GL_TEXTURE_RECTANGLE_NV && tobj->target==GL_TEXTURE_2D)
+ ||(target==GL_TEXTURE_2D && tobj->target==GL_TEXTURE_RECTANGLE_NV)))
+ {
+ crWarning( "You called glBindTexture with a target of 0x%x, but the texture you wanted was target 0x%x [1D: %x 2D: %x 3D: %x cube: %x]", (int) target, (int) tobj->target, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP );
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "Attempt to bind a texture of different dimensions");
+ return;
+ }
+
+ /* Set the current texture */
+ switch (target)
+ {
+ case GL_TEXTURE_1D:
+ t->unit[t->curTextureUnit].currentTexture1D = tobj;
+ break;
+ case GL_TEXTURE_2D:
+ t->unit[t->curTextureUnit].currentTexture2D = tobj;
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_3D:
+ t->unit[t->curTextureUnit].currentTexture3D = tobj;
+ break;
+#endif
+#ifdef CR_ARB_texture_cube_map
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ t->unit[t->curTextureUnit].currentTextureCubeMap = tobj;
+ break;
+#endif
+#ifdef CR_NV_texture_rectangle
+ case GL_TEXTURE_RECTANGLE_NV:
+ t->unit[t->curTextureUnit].currentTextureRect = tobj;
+ break;
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "Invalid target passed to glBindTexture: %d", target);
+ return;
+ }
+
+ DIRTY(tb->dirty, g->neg_bitid);
+ DIRTY(tb->current[t->curTextureUnit], g->neg_bitid);
+}
+
+
+void STATE_APIENTRY
+crStateTexParameterfv(GLenum target, GLenum pname, const GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj = NULL;
+ CRTextureLevel *tl = NULL;
+ GLenum e = (GLenum) *param;
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+ unsigned int i;
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "TexParameterfv called in Begin/End");
+ return;
+ }
+
+ crStateGetTextureObjectAndImage(g, target, 0, &tobj, &tl);
+ if (!tobj) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParamterfv(invalid target=0x%x)", target);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ if (e != GL_NEAREST &&
+ e != GL_LINEAR &&
+ e != GL_NEAREST_MIPMAP_NEAREST &&
+ e != GL_LINEAR_MIPMAP_NEAREST &&
+ e != GL_NEAREST_MIPMAP_LINEAR &&
+ e != GL_LINEAR_MIPMAP_LINEAR)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParamterfv: GL_TEXTURE_MIN_FILTER invalid param: %d", e);
+ return;
+ }
+ tobj->minFilter = e;
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ if (e != GL_NEAREST && e != GL_LINEAR)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParamterfv: GL_TEXTURE_MAG_FILTER invalid param: %d", e);
+ return;
+ }
+ tobj->magFilter = e;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ if (e == GL_CLAMP || e == GL_REPEAT) {
+ tobj->wrapS = e;
+ }
+#ifdef CR_OPENGL_VERSION_1_2
+ else if (e == GL_CLAMP_TO_EDGE) {
+ tobj->wrapS = e;
+ }
+#endif
+#ifdef GL_CLAMP_TO_EDGE_EXT
+ else if (e == GL_CLAMP_TO_EDGE_EXT && g->extensions.EXT_texture_edge_clamp) {
+ tobj->wrapS = e;
+ }
+#endif
+#ifdef CR_ARB_texture_border_clamp
+ else if (e == GL_CLAMP_TO_BORDER_ARB && g->extensions.ARB_texture_border_clamp) {
+ tobj->wrapS = e;
+ }
+#endif
+#ifdef CR_ARB_texture_mirrored_repeat
+ else if (e == GL_MIRRORED_REPEAT_ARB && g->extensions.ARB_texture_mirrored_repeat) {
+ tobj->wrapS = e;
+ }
+#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapS = e;
+ }
+#endif
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParameterfv: GL_TEXTURE_WRAP_S invalid param: 0x%x", e);
+ return;
+ }
+ break;
+ case GL_TEXTURE_WRAP_T:
+ if (e == GL_CLAMP || e == GL_REPEAT) {
+ tobj->wrapT = e;
+ }
+#ifdef CR_OPENGL_VERSION_1_2
+ else if (e == GL_CLAMP_TO_EDGE) {
+ tobj->wrapT = e;
+ }
+#endif
+#ifdef GL_CLAMP_TO_EDGE_EXT
+ else if (e == GL_CLAMP_TO_EDGE_EXT && g->extensions.EXT_texture_edge_clamp) {
+ tobj->wrapT = e;
+ }
+#endif
+#ifdef CR_ARB_texture_border_clamp
+ else if (e == GL_CLAMP_TO_BORDER_ARB && g->extensions.ARB_texture_border_clamp) {
+ tobj->wrapT = e;
+ }
+#endif
+#ifdef CR_ARB_texture_mirrored_repeat
+ else if (e == GL_MIRRORED_REPEAT_ARB && g->extensions.ARB_texture_mirrored_repeat) {
+ tobj->wrapT = e;
+ }
+#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapT = e;
+ }
+#endif
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParameterfv: GL_TEXTURE_WRAP_T invalid param: 0x%x", e);
+ return;
+ }
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_WRAP_R:
+ if (e == GL_CLAMP || e == GL_REPEAT) {
+ tobj->wrapR = e;
+ }
+ else if (e == GL_CLAMP_TO_EDGE) {
+ tobj->wrapR = e;
+ }
+#ifdef GL_CLAMP_TO_EDGE_EXT
+ else if (e == GL_CLAMP_TO_EDGE_EXT && g->extensions.EXT_texture_edge_clamp) {
+ tobj->wrapR = e;
+ }
+#endif
+#ifdef CR_ARB_texture_border_clamp
+ else if (e == GL_CLAMP_TO_BORDER_ARB && g->extensions.ARB_texture_border_clamp) {
+ tobj->wrapR = e;
+ }
+#endif
+#ifdef CR_ARB_texture_mirrored_repeat
+ else if (e == GL_MIRRORED_REPEAT_ARB && g->extensions.ARB_texture_mirrored_repeat) {
+ tobj->wrapR = e;
+ }
+#endif
+#ifdef CR_ATI_texture_mirror_once
+ else if ((e == GL_MIRROR_CLAMP_ATI || e == GL_MIRROR_CLAMP_TO_EDGE_ATI) && g->extensions.ATI_texture_mirror_once) {
+ tobj->wrapR = e;
+ }
+#endif
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParameterfv: GL_TEXTURE_WRAP_R invalid param: 0x%x", e);
+ return;
+ }
+ break;
+ case GL_TEXTURE_PRIORITY:
+ tobj->priority = param[0];
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ tobj->minLod = param[0];
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ tobj->maxLod = param[0];
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ if (e < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParameterfv: GL_TEXTURE_BASE_LEVEL invalid param: 0x%x", e);
+ return;
+ }
+ tobj->baseLevel = e;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ if (e < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParameterfv: GL_TEXTURE_MAX_LEVEL invalid param: 0x%x", e);
+ return;
+ }
+ tobj->maxLevel = e;
+ break;
+#endif
+ case GL_TEXTURE_BORDER_COLOR:
+ tobj->borderColor.r = param[0];
+ tobj->borderColor.g = param[1];
+ tobj->borderColor.b = param[2];
+ tobj->borderColor.a = param[3];
+ break;
+#ifdef CR_EXT_texture_filter_anisotropic
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (g->extensions.EXT_texture_filter_anisotropic) {
+ if (param[0] < 1.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "TexParameterfv: GL_TEXTURE_MAX_ANISOTROPY_EXT called with parameter less than 1: %f", param[0]);
+ return;
+ }
+ tobj->maxAnisotropy = param[0];
+ if (tobj->maxAnisotropy > g->limits.maxTextureAnisotropy)
+ {
+ tobj->maxAnisotropy = g->limits.maxTextureAnisotropy;
+ }
+ }
+ break;
+#endif
+#ifdef CR_ARB_depth_texture
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (g->extensions.ARB_depth_texture) {
+ if (param[0] == GL_LUMINANCE ||
+ param[0] == GL_INTENSITY ||
+ param[0] == GL_ALPHA) {
+ tobj->depthMode = (GLenum) param[0];
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "TexParameterfv: GL_DEPTH_TEXTURE_MODE_ARB called with invalid parameter: 0x%x", param[0]);
+ return;
+ }
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (g->extensions.ARB_shadow) {
+ if (param[0] == GL_NONE ||
+ param[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ tobj->compareMode = (GLenum) param[0];
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "TexParameterfv: GL_TEXTURE_COMPARE_MODE_ARB called with invalid parameter: 0x%x", param[0]);
+ return;
+ }
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (g->extensions.ARB_shadow) {
+ if (param[0] == GL_LEQUAL ||
+ param[0] == GL_GEQUAL) {
+ tobj->compareFunc = (GLenum) param[0];
+ }
+ }
+#ifdef CR_EXT_shadow_funcs
+ else if (g->extensions.EXT_shadow_funcs) {
+ if (param[0] == GL_LEQUAL ||
+ param[0] == GL_GEQUAL ||
+ param[0] == GL_LESS ||
+ param[0] == GL_GREATER ||
+ param[0] == GL_ALWAYS ||
+ param[0] == GL_NEVER ) {
+ tobj->compareFunc = (GLenum) param[0];
+ }
+ }
+#endif
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "TexParameterfv: GL_TEXTURE_COMPARE_FUNC_ARB called with invalid parameter: 0x%x", param[0]);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow_ambient
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (g->extensions.ARB_shadow_ambient) {
+ tobj->compareFailValue = param[0];
+ }
+ break;
+#endif
+#ifdef CR_SGIS_generate_mipmap
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (g->extensions.SGIS_generate_mipmap) {
+ tobj->generateMipmap = param[0] ? GL_TRUE : GL_FALSE;
+ }
+ break;
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParamterfv: Invalid pname: %d", pname);
+ return;
+ }
+
+ DIRTY(tobj->dirty, g->neg_bitid);
+ for (i = 0; i < g->limits.maxTextureUnits; i++)
+ {
+ DIRTY(tobj->paramsBit[i], g->neg_bitid);
+ }
+ DIRTY(tb->dirty, g->neg_bitid);
+}
+
+
+void STATE_APIENTRY
+crStateTexParameteriv(GLenum target, GLenum pname, const GLint *param)
+{
+ GLfloat f_param;
+ GLcolor f_color;
+ switch (pname)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_PRIORITY:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+#endif
+#ifdef CR_EXT_texture_filter_anisotropic
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+#endif
+#ifdef CR_ARB_depth_texture
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+#endif
+#ifdef CR_ARB_shadow
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+#endif
+#ifdef CR_ARB_shadow_ambinet
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+#endif
+#ifdef CR_SGIS_generate_mipmap
+ case GL_GENERATE_MIPMAP_SGIS:
+#endif
+ f_param = (GLfloat) (*param);
+ crStateTexParameterfv( target, pname, &(f_param) );
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ f_color.r = ((GLfloat) param[0])/CR_MAXINT;
+ f_color.g = ((GLfloat) param[1])/CR_MAXINT;
+ f_color.b = ((GLfloat) param[2])/CR_MAXINT;
+ f_color.a = ((GLfloat) param[3])/CR_MAXINT;
+ crStateTexParameterfv( target, pname, (const GLfloat *) &(f_color) );
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "TexParamteriv: Invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ crStateTexParameterfv( target, pname, &param );
+}
+
+
+void STATE_APIENTRY
+crStateTexParameteri(GLenum target, GLenum pname, GLint param) {
+ GLfloat f_param = (GLfloat) param;
+ crStateTexParameterfv( target, pname, &f_param );
+}
+
+
+void STATE_APIENTRY
+crStateTexEnvfv(GLenum target, GLenum pname, const GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+ GLenum e;
+ GLcolorf c;
+ GLuint stage = 0;
+
+ (void) stage;
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glTexEnvfv called in begin/end");
+ return;
+ }
+
+#if CR_EXT_texture_lod_bias
+ if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ if (!g->extensions.EXT_texture_lod_bias || pname != GL_TEXTURE_LOD_BIAS_EXT) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnv");
+ }
+ else {
+ t->unit[t->curTextureUnit].lodBias = *param;
+ DIRTY(tb->envBit[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ }
+ return;
+ }
+ else
+#endif
+#if CR_ARB_point_sprite
+ if (target == GL_POINT_SPRITE_ARB) {
+ if (!g->extensions.ARB_point_sprite || pname != GL_COORD_REPLACE_ARB) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnv");
+ }
+ else {
+ CRPointBits *pb = &(sb->point);
+ g->point.coordReplacement[t->curTextureUnit] = *param ? GL_TRUE : GL_FALSE;
+ DIRTY(pb->coordReplacement[t->curTextureUnit], g->neg_bitid);
+ DIRTY(pb->dirty, g->neg_bitid);
+ }
+ return;
+ }
+ else
+#endif
+ if (target != GL_TEXTURE_ENV)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexEnvfv: target != GL_TEXTURE_ENV: %d", target);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_ENV_MODE:
+ e = (GLenum) *param;
+ if (e != GL_MODULATE &&
+ e != GL_DECAL &&
+ e != GL_BLEND &&
+ e != GL_ADD &&
+ e != GL_REPLACE &&
+ e != GL_COMBINE_ARB)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexEnvfv: invalid param: %f", *param);
+ return;
+ }
+ t->unit[t->curTextureUnit].envMode = e;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ c.r = param[0];
+ c.g = param[1];
+ c.b = param[2];
+ c.a = param[3];
+ if (c.r > 1.0f) c.r = 1.0f;
+ if (c.g > 1.0f) c.g = 1.0f;
+ if (c.b > 1.0f) c.b = 1.0f;
+ if (c.a > 1.0f) c.a = 1.0f;
+ if (c.r < 0.0f) c.r = 0.0f;
+ if (c.g < 0.0f) c.g = 0.0f;
+ if (c.b < 0.0f) c.b = 0.0f;
+ if (c.a < 0.0f) c.a = 0.0f;
+ t->unit[t->curTextureUnit].envColor = c;
+ break;
+
+#ifdef CR_ARB_texture_env_combine
+ case GL_COMBINE_RGB_ARB:
+ e = (GLenum) (GLint) *param;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_REPLACE ||
+ e == GL_MODULATE ||
+ e == GL_ADD ||
+ e == GL_ADD_SIGNED_ARB ||
+ e == GL_INTERPOLATE_ARB ||
+ e == GL_SUBTRACT_ARB)) {
+ t->unit[t->curTextureUnit].combineModeRGB = e;
+ }
+#ifdef CR_ARB_texture_env_dot3
+ else if (g->extensions.ARB_texture_env_dot3 &&
+ (e == GL_DOT3_RGB_ARB ||
+ e == GL_DOT3_RGBA_ARB ||
+ e == GL_DOT3_RGB_EXT ||
+ e == GL_DOT3_RGBA_EXT)) {
+ t->unit[t->curTextureUnit].combineModeRGB = e;
+ }
+#endif
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv(param=0x%x", e);
+ return;
+ }
+ break;
+ case GL_COMBINE_ALPHA_EXT:
+ e = (GLenum) *param;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_REPLACE ||
+ e == GL_MODULATE ||
+ e == GL_ADD ||
+ e == GL_ADD_SIGNED_ARB ||
+ e == GL_INTERPOLATE_ARB ||
+ e == GL_SUBTRACT_ARB)) {
+ t->unit[t->curTextureUnit].combineModeA = e;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv");
+ return;
+ }
+ break;
+ case GL_SOURCE0_RGB_ARB:
+ case GL_SOURCE1_RGB_ARB:
+ case GL_SOURCE2_RGB_ARB:
+ e = (GLenum) *param;
+ stage = pname - GL_SOURCE0_RGB_ARB;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_TEXTURE ||
+ e == GL_CONSTANT_ARB ||
+ e == GL_PRIMARY_COLOR_ARB ||
+ e == GL_PREVIOUS_ARB)) {
+ t->unit[t->curTextureUnit].combineSourceRGB[stage] = e;
+ }
+ else if (g->extensions.ARB_texture_env_crossbar &&
+ e >= GL_TEXTURE0_ARB &&
+ e < GL_TEXTURE0_ARB + g->limits.maxTextureUnits) {
+ t->unit[t->curTextureUnit].combineSourceRGB[stage] = e;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv");
+ return;
+ }
+ break;
+ case GL_SOURCE0_ALPHA_ARB:
+ case GL_SOURCE1_ALPHA_ARB:
+ case GL_SOURCE2_ALPHA_ARB:
+ e = (GLenum) *param;
+ stage = pname - GL_SOURCE0_ALPHA_ARB;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_TEXTURE ||
+ e == GL_CONSTANT_ARB ||
+ e == GL_PRIMARY_COLOR_ARB ||
+ e == GL_PREVIOUS_ARB)) {
+ t->unit[t->curTextureUnit].combineSourceA[stage] = e;
+ }
+ else if (g->extensions.ARB_texture_env_crossbar &&
+ e >= GL_TEXTURE0_ARB &&
+ e < GL_TEXTURE0_ARB + g->limits.maxTextureUnits) {
+ t->unit[t->curTextureUnit].combineSourceA[stage] = e;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv");
+ return;
+ }
+ break;
+ case GL_OPERAND0_RGB_ARB:
+ case GL_OPERAND1_RGB_ARB:
+ case GL_OPERAND2_RGB_ARB:
+ e = (GLenum) *param;
+ stage = pname - GL_OPERAND0_RGB_ARB;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_SRC_COLOR ||
+ e == GL_ONE_MINUS_SRC_COLOR ||
+ e == GL_SRC_ALPHA ||
+ e == GL_ONE_MINUS_SRC_ALPHA)) {
+ t->unit[t->curTextureUnit].combineOperandRGB[stage] = e;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv");
+ return;
+ }
+ break;
+ case GL_OPERAND0_ALPHA_ARB:
+ case GL_OPERAND1_ALPHA_ARB:
+ case GL_OPERAND2_ALPHA_ARB:
+ e = (GLenum) *param;
+ stage = pname - GL_OPERAND0_ALPHA_ARB;
+ if (g->extensions.ARB_texture_env_combine &&
+ (e == GL_SRC_ALPHA ||
+ e == GL_ONE_MINUS_SRC_ALPHA)) {
+ t->unit[t->curTextureUnit].combineOperandA[stage] = e;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexEnvfv(param=0x%x)", e);
+ return;
+ }
+ break;
+ case GL_RGB_SCALE_ARB:
+ if (g->extensions.ARB_texture_env_combine &&
+ (*param == 1.0 ||
+ *param == 2.0 ||
+ *param == 4.0)) {
+ t->unit[t->curTextureUnit].combineScaleRGB = *param;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexEnvfv");
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (g->extensions.ARB_texture_env_combine &&
+ (*param == 1.0 ||
+ *param == 2.0 ||
+ *param == 4.0)) {
+ t->unit[t->curTextureUnit].combineScaleA = *param;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexEnvfv");
+ return;
+ }
+ break;
+#endif /* CR_ARB_texture_env_combine */
+
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexEnvfv: invalid pname: %d", pname);
+ return;
+ }
+
+ DIRTY(tb->envBit[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+}
+
+
+void STATE_APIENTRY
+crStateTexEnviv(GLenum target, GLenum pname, const GLint *param)
+{
+ GLfloat f_param;
+ GLcolor f_color;
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ f_param = (GLfloat) (*param);
+ crStateTexEnvfv( target, pname, &f_param );
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ f_color.r = ((GLfloat) param[0]) / CR_MAXINT;
+ f_color.g = ((GLfloat) param[1]) / CR_MAXINT;
+ f_color.b = ((GLfloat) param[2]) / CR_MAXINT;
+ f_color.a = ((GLfloat) param[3]) / CR_MAXINT;
+ crStateTexEnvfv( target, pname, (const GLfloat *) &f_color );
+ break;
+#ifdef CR_ARB_texture_env_combine
+ case GL_COMBINE_RGB_ARB:
+ case GL_COMBINE_ALPHA_EXT:
+ case GL_SOURCE0_RGB_ARB:
+ case GL_SOURCE1_RGB_ARB:
+ case GL_SOURCE2_RGB_ARB:
+ case GL_SOURCE0_ALPHA_ARB:
+ case GL_SOURCE1_ALPHA_ARB:
+ case GL_SOURCE2_ALPHA_ARB:
+ case GL_OPERAND0_RGB_ARB:
+ case GL_OPERAND1_RGB_ARB:
+ case GL_OPERAND2_RGB_ARB:
+ case GL_OPERAND0_ALPHA_ARB:
+ case GL_OPERAND1_ALPHA_ARB:
+ case GL_OPERAND2_ALPHA_ARB:
+ case GL_RGB_SCALE_ARB:
+ case GL_ALPHA_SCALE:
+ f_param = (GLfloat) (*param);
+ crStateTexEnvfv( target, pname, &f_param );
+ break;
+#endif
+#ifdef CR_EXT_texture_lod_bias
+ case GL_TEXTURE_LOD_BIAS_EXT:
+ f_param = (GLfloat) (*param);
+ crStateTexEnvfv( target, pname, &f_param);
+ break;
+#endif
+#ifdef CR_ARB_point_sprite
+ case GL_COORD_REPLACE_ARB:
+ f_param = (GLfloat) *param;
+ crStateTexEnvfv( target, pname, &f_param);
+ break;
+#endif
+
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexEnvfv: invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ crStateTexEnvfv( target, pname, &param );
+}
+
+
+void STATE_APIENTRY
+crStateTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ GLfloat f_param = (GLfloat) param;
+ crStateTexEnvfv( target, pname, &f_param );
+}
+
+
+void STATE_APIENTRY
+crStateGetTexEnvfv(GLenum target, GLenum pname, GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__,GL_INVALID_OPERATION,
+ "glGetTexEnvfv called in begin/end");
+ return;
+ }
+
+#if CR_EXT_texture_lod_bias
+ if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ if (!g->extensions.EXT_texture_lod_bias || pname != GL_TEXTURE_LOD_BIAS_EXT) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnv");
+ }
+ else {
+ *param = t->unit[t->curTextureUnit].lodBias;
+ }
+ return;
+ }
+ else
+#endif
+#if CR_ARB_point_sprite
+ if (target == GL_POINT_SPRITE_ARB) {
+ if (!g->extensions.ARB_point_sprite || pname != GL_COORD_REPLACE_ARB) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnv");
+ }
+ else {
+ *param = (GLfloat) g->point.coordReplacement[t->curTextureUnit];
+ }
+ return;
+ }
+ else
+#endif
+ if (target != GL_TEXTURE_ENV)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexEnvfv: target != GL_TEXTURE_ENV: %d", target);
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ *param = (GLfloat) t->unit[t->curTextureUnit].envMode;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ param[0] = t->unit[t->curTextureUnit].envColor.r;
+ param[1] = t->unit[t->curTextureUnit].envColor.g;
+ param[2] = t->unit[t->curTextureUnit].envColor.b;
+ param[3] = t->unit[t->curTextureUnit].envColor.a;
+ break;
+ case GL_COMBINE_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineModeRGB;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_COMBINE_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineModeA;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE0_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceRGB[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE1_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceRGB[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE2_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceRGB[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE0_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceA[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE1_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceA[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE2_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineSourceA[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND0_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandRGB[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND1_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandRGB[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND2_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandRGB[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND0_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandA[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND1_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandA[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND2_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLfloat) t->unit[t->curTextureUnit].combineOperandA[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_RGB_SCALE_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = t->unit[t->curTextureUnit].combineScaleRGB;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = t->unit[t->curTextureUnit].combineScaleA;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexEnvfv: invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexEnviv(GLenum target, GLenum pname, GLint *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__,GL_INVALID_OPERATION,
+ "glGetTexEnviv called in begin/end");
+ return;
+ }
+
+#if CR_EXT_texture_lod_bias
+ if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
+ if (!g->extensions.EXT_texture_lod_bias || pname != GL_TEXTURE_LOD_BIAS_EXT) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnv");
+ }
+ else {
+ *param = (GLint) t->unit[t->curTextureUnit].lodBias;
+ }
+ return;
+ }
+ else
+#endif
+#if CR_ARB_point_sprite
+ if (target == GL_POINT_SPRITE_ARB) {
+ if (!g->extensions.ARB_point_sprite || pname != GL_COORD_REPLACE_ARB) {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnv");
+ }
+ else {
+ *param = (GLint) g->point.coordReplacement[t->curTextureUnit];
+ }
+ return;
+ }
+ else
+#endif
+ if (target != GL_TEXTURE_ENV)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexEnviv: target != GL_TEXTURE_ENV: %d", target);
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_MODE:
+ *param = (GLint) t->unit[t->curTextureUnit].envMode;
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ param[0] = (GLint) (t->unit[t->curTextureUnit].envColor.r * CR_MAXINT);
+ param[1] = (GLint) (t->unit[t->curTextureUnit].envColor.g * CR_MAXINT);
+ param[2] = (GLint) (t->unit[t->curTextureUnit].envColor.b * CR_MAXINT);
+ param[3] = (GLint) (t->unit[t->curTextureUnit].envColor.a * CR_MAXINT);
+ break;
+ case GL_COMBINE_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineModeRGB;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_COMBINE_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineModeA;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE0_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceRGB[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE1_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceRGB[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE2_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceRGB[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE0_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceA[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE1_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceA[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_SOURCE2_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineSourceA[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND0_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandRGB[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND1_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandRGB[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND2_RGB_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandRGB[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND0_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandA[0];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND1_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandA[1];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_OPERAND2_ALPHA_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineOperandA[2];
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_RGB_SCALE_ARB:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineScaleRGB;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ case GL_ALPHA_SCALE:
+ if (g->extensions.ARB_texture_env_combine) {
+ *param = (GLint) t->unit[t->curTextureUnit].combineScaleA;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexEnviv: invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexGendv(GLenum coord, GLenum pname, const GLdouble *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTransformState *trans = &(g->transform);
+ GLvectorf v;
+ GLenum e;
+ CRmatrix inv;
+ CRStateBits *sb = GetCurrentBits();
+ CRTextureBits *tb = &(sb->texture);
+
+ FLUSH();
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glTexGen called in begin/end");
+ return;
+ }
+
+ switch (coord)
+ {
+ case GL_S:
+ switch (pname)
+ {
+ case GL_TEXTURE_GEN_MODE:
+ e = (GLenum) *param;
+ if (e == GL_OBJECT_LINEAR ||
+ e == GL_EYE_LINEAR ||
+ e == GL_SPHERE_MAP
+#if defined(GL_ARB_texture_cube_map) || defined(GL_EXT_texture_cube_map) || defined(GL_NV_texgen_reflection)
+ || ((e == GL_REFLECTION_MAP_ARB || e == GL_NORMAL_MAP_ARB)
+ && g->extensions.ARB_texture_cube_map)
+#endif
+ ) {
+ t->unit[t->curTextureUnit].gen.s = e;
+ DIRTY(tb->genMode[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGendv called with bad param: %lf", *param);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ t->unit[t->curTextureUnit].objSCoeff = v;
+ DIRTY(tb->objGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ case GL_EYE_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ crMatrixInvertTranspose(&inv, trans->modelViewStack.top);
+ crStateTransformXformPointMatrixf(&inv, &v);
+ t->unit[t->curTextureUnit].eyeSCoeff = v;
+ DIRTY(tb->eyeGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGendv called with bogus pname: %d", pname);
+ return;
+ }
+ break;
+ case GL_T:
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ e = (GLenum) *param;
+ if (e == GL_OBJECT_LINEAR ||
+ e == GL_EYE_LINEAR ||
+ e == GL_SPHERE_MAP
+#if defined(GL_ARB_texture_cube_map) || defined(GL_EXT_texture_cube_map) || defined(GL_NV_texgen_reflection)
+ || ((e == GL_REFLECTION_MAP_ARB || e == GL_NORMAL_MAP_ARB)
+ && g->extensions.ARB_texture_cube_map)
+#endif
+ ) {
+ t->unit[t->curTextureUnit].gen.t = e;
+ DIRTY(tb->genMode[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGendv called with bad param: %lf", *param);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ t->unit[t->curTextureUnit].objTCoeff = v;
+ DIRTY(tb->objGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ case GL_EYE_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ crMatrixInvertTranspose(&inv, trans->modelViewStack.top);
+ crStateTransformXformPointMatrixf(&inv, &v);
+ t->unit[t->curTextureUnit].eyeTCoeff = v;
+ DIRTY(tb->eyeGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus pname: %d", pname);
+ return;
+ }
+ break;
+ case GL_R:
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ e = (GLenum) *param;
+ if (e == GL_OBJECT_LINEAR ||
+ e == GL_EYE_LINEAR ||
+ e == GL_SPHERE_MAP
+#if defined(GL_ARB_texture_cube_map) || defined(GL_EXT_texture_cube_map) || defined(GL_NV_texgen_reflection)
+ || ((e == GL_REFLECTION_MAP_ARB || e == GL_NORMAL_MAP_ARB)
+ && g->extensions.ARB_texture_cube_map)
+#endif
+ ) {
+ t->unit[t->curTextureUnit].gen.r = e;
+ DIRTY(tb->genMode[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bad param: %lf", *param);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ t->unit[t->curTextureUnit].objRCoeff = v;
+ DIRTY(tb->objGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ case GL_EYE_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ crMatrixInvertTranspose(&inv, trans->modelViewStack.top);
+ crStateTransformXformPointMatrixf(&inv, &v);
+ t->unit[t->curTextureUnit].eyeRCoeff = v;
+ DIRTY(tb->eyeGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus pname: %d", pname);
+ return;
+ }
+ break;
+ case GL_Q:
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ e = (GLenum) *param;
+ if (e == GL_OBJECT_LINEAR ||
+ e == GL_EYE_LINEAR ||
+ e == GL_SPHERE_MAP
+#if defined(GL_ARB_texture_cube_map) || defined(GL_EXT_texture_cube_map) || defined(GL_NV_texgen_reflection)
+ || ((e == GL_REFLECTION_MAP_ARB || e == GL_NORMAL_MAP_ARB)
+ && g->extensions.ARB_texture_cube_map)
+#endif
+ ) {
+ t->unit[t->curTextureUnit].gen.q = e;
+ DIRTY(tb->genMode[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bad param: %lf", *param);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ t->unit[t->curTextureUnit].objQCoeff = v;
+ DIRTY(tb->objGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ case GL_EYE_PLANE:
+ v.x = (GLfloat) param[0];
+ v.y = (GLfloat) param[1];
+ v.z = (GLfloat) param[2];
+ v.w = (GLfloat) param[3];
+ crMatrixInvertTranspose(&inv, trans->modelViewStack.top);
+ crStateTransformXformPointMatrixf(&inv, &v);
+ t->unit[t->curTextureUnit].eyeQCoeff = v;
+ DIRTY(tb->eyeGen[t->curTextureUnit], g->neg_bitid);
+ DIRTY(tb->dirty, g->neg_bitid);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus pname: %d", pname);
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus coord: %d", coord);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexGenfv(GLenum coord, GLenum pname, const GLfloat *param)
+{
+ GLdouble d_param;
+ GLvectord d_vector;
+ switch (pname)
+ {
+ case GL_TEXTURE_GEN_MODE:
+ d_param = (GLdouble) *param;
+ crStateTexGendv( coord, pname, &d_param );
+ break;
+ case GL_OBJECT_PLANE:
+ case GL_EYE_PLANE:
+ d_vector.x = (GLdouble) param[0];
+ d_vector.y = (GLdouble) param[1];
+ d_vector.z = (GLdouble) param[2];
+ d_vector.w = (GLdouble) param[3];
+ crStateTexGendv( coord, pname, (const double *) &d_vector );
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexGeniv(GLenum coord, GLenum pname, const GLint *param)
+{
+ GLdouble d_param;
+ GLvectord d_vector;
+ switch (pname)
+ {
+ case GL_TEXTURE_GEN_MODE:
+ d_param = (GLdouble) *param;
+ crStateTexGendv( coord, pname, &d_param );
+ break;
+ case GL_OBJECT_PLANE:
+ case GL_EYE_PLANE:
+ d_vector.x = (GLdouble) param[0];
+ d_vector.y = (GLdouble) param[1];
+ d_vector.z = (GLdouble) param[2];
+ d_vector.w = (GLdouble) param[3];
+ crStateTexGendv( coord, pname, (const double *) &d_vector );
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glTexGen called with bogus pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateTexGend (GLenum coord, GLenum pname, GLdouble param)
+{
+ crStateTexGendv( coord, pname, &param );
+}
+
+
+void STATE_APIENTRY
+crStateTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ GLdouble d_param = (GLdouble) param;
+ crStateTexGendv( coord, pname, &d_param );
+}
+
+
+void STATE_APIENTRY
+crStateTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ GLdouble d_param = (GLdouble) param;
+ crStateTexGendv( coord, pname, &d_param );
+}
+
+
+void STATE_APIENTRY
+crStateGetTexGendv(GLenum coord, GLenum pname, GLdouble *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexGen called in begin/end");
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ switch (coord) {
+ case GL_S:
+ *param = (GLdouble) t->unit[t->curTextureUnit].gen.s;
+ break;
+ case GL_T:
+ *param = (GLdouble) t->unit[t->curTextureUnit].gen.t;
+ break;
+ case GL_R:
+ *param = (GLdouble) t->unit[t->curTextureUnit].gen.r;
+ break;
+ case GL_Q:
+ *param = (GLdouble) t->unit[t->curTextureUnit].gen.q;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGen called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].objSCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].objSCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].objSCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].objSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].objTCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].objTCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].objTCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].objTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].objRCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].objRCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].objRCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].objRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].objQCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].objQCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].objQCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].objQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGen called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_EYE_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].eyeSCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].eyeSCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].eyeSCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].eyeSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].eyeTCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].eyeTCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].eyeTCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].eyeTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].eyeRCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].eyeRCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].eyeRCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].eyeRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = (GLdouble) t->unit[t->curTextureUnit].eyeQCoeff.x;
+ param[1] = (GLdouble) t->unit[t->curTextureUnit].eyeQCoeff.y;
+ param[2] = (GLdouble) t->unit[t->curTextureUnit].eyeQCoeff.z;
+ param[3] = (GLdouble) t->unit[t->curTextureUnit].eyeQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGen called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGen called with bogus pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexGenfv(GLenum coord, GLenum pname, GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexGenfv called in begin/end");
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ switch (coord) {
+ case GL_S:
+ *param = (GLfloat) t->unit[t->curTextureUnit].gen.s;
+ break;
+ case GL_T:
+ *param = (GLfloat) t->unit[t->curTextureUnit].gen.t;
+ break;
+ case GL_R:
+ *param = (GLfloat) t->unit[t->curTextureUnit].gen.r;
+ break;
+ case GL_Q:
+ *param = (GLfloat) t->unit[t->curTextureUnit].gen.q;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGenfv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = t->unit[t->curTextureUnit].objSCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].objSCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].objSCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].objSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = t->unit[t->curTextureUnit].objTCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].objTCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].objTCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].objTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = t->unit[t->curTextureUnit].objRCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].objRCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].objRCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].objRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = t->unit[t->curTextureUnit].objQCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].objQCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].objQCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].objQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGenfv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_EYE_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = t->unit[t->curTextureUnit].eyeSCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].eyeSCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].eyeSCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].eyeSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = t->unit[t->curTextureUnit].eyeTCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].eyeTCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].eyeTCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].eyeTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = t->unit[t->curTextureUnit].eyeRCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].eyeRCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].eyeRCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].eyeRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = t->unit[t->curTextureUnit].eyeQCoeff.x;
+ param[1] = t->unit[t->curTextureUnit].eyeQCoeff.y;
+ param[2] = t->unit[t->curTextureUnit].eyeQCoeff.z;
+ param[3] = t->unit[t->curTextureUnit].eyeQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGenfv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGenfv called with bogus pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexGeniv(GLenum coord, GLenum pname, GLint *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexGeniv called in begin/end");
+ return;
+ }
+
+ switch (pname) {
+ case GL_TEXTURE_GEN_MODE:
+ switch (coord) {
+ case GL_S:
+ *param = (GLint) t->unit[t->curTextureUnit].gen.s;
+ break;
+ case GL_T:
+ *param = (GLint) t->unit[t->curTextureUnit].gen.t;
+ break;
+ case GL_R:
+ *param = (GLint) t->unit[t->curTextureUnit].gen.r;
+ break;
+ case GL_Q:
+ *param = (GLint) t->unit[t->curTextureUnit].gen.q;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGeniv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_OBJECT_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = (GLint) t->unit[t->curTextureUnit].objSCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].objSCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].objSCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].objSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = (GLint) t->unit[t->curTextureUnit].objTCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].objTCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].objTCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].objTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = (GLint) t->unit[t->curTextureUnit].objRCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].objRCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].objRCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].objRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = (GLint) t->unit[t->curTextureUnit].objQCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].objQCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].objQCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].objQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGeniv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ case GL_EYE_PLANE:
+ switch (coord) {
+ case GL_S:
+ param[0] = (GLint) t->unit[t->curTextureUnit].eyeSCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].eyeSCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].eyeSCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].eyeSCoeff.w;
+ break;
+ case GL_T:
+ param[0] = (GLint) t->unit[t->curTextureUnit].eyeTCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].eyeTCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].eyeTCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].eyeTCoeff.w;
+ break;
+ case GL_R:
+ param[0] = (GLint) t->unit[t->curTextureUnit].eyeRCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].eyeRCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].eyeRCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].eyeRCoeff.w;
+ break;
+ case GL_Q:
+ param[0] = (GLint) t->unit[t->curTextureUnit].eyeQCoeff.x;
+ param[1] = (GLint) t->unit[t->curTextureUnit].eyeQCoeff.y;
+ param[2] = (GLint) t->unit[t->curTextureUnit].eyeQCoeff.z;
+ param[3] = (GLint) t->unit[t->curTextureUnit].eyeQCoeff.w;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGeniv called with bogus coord: %d", coord);
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexGen called with bogus pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexLevelParameterfv(GLenum target, GLint level,
+ GLenum pname, GLfloat *params)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTextureObj *tobj;
+ CRTextureLevel *timg;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexLevelParameterfv called in begin/end");
+ return;
+ }
+
+ if (level < 0 || level > t->maxLevel)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "glGetTexLevelParameterfv: Invalid level: %d", level);
+ return;
+ }
+
+ crStateGetTextureObjectAndImage(g, target, level, &tobj, &timg);
+ if (!timg)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "GetTexLevelParameterfv: invalid target: 0x%x or level %d",
+ target, level);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WIDTH:
+ *params = (GLfloat) timg->width;
+ break;
+ case GL_TEXTURE_HEIGHT:
+ *params = (GLfloat) timg->height;
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_DEPTH:
+ *params = (GLfloat) timg->depth;
+ break;
+#endif
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ *params = (GLfloat) timg->internalFormat;
+ break;
+ case GL_TEXTURE_BORDER:
+ *params = (GLfloat) timg->border;
+ break;
+ case GL_TEXTURE_RED_SIZE:
+ *params = (GLfloat) timg->texFormat->redbits;
+ break;
+ case GL_TEXTURE_GREEN_SIZE:
+ *params = (GLfloat) timg->texFormat->greenbits;
+ break;
+ case GL_TEXTURE_BLUE_SIZE:
+ *params = (GLfloat) timg->texFormat->bluebits;
+ break;
+ case GL_TEXTURE_ALPHA_SIZE:
+ *params = (GLfloat) timg->texFormat->alphabits;
+ break;
+ case GL_TEXTURE_INTENSITY_SIZE:
+ *params = (GLfloat) timg->texFormat->intensitybits;
+ break;
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ *params = (GLfloat) timg->texFormat->luminancebits;
+ break;
+#if CR_ARB_texture_compression
+ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
+ *params = (GLfloat) timg->bytes;
+ break;
+ case GL_TEXTURE_COMPRESSED_ARB:
+ *params = (GLfloat) timg->compressed;
+ break;
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "GetTexLevelParameterfv: invalid pname: 0x%x",
+ pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexLevelParameteriv(GLenum target, GLint level,
+ GLenum pname, GLint *params)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureState *t = &(g->texture);
+ CRTextureObj *tobj;
+ CRTextureLevel *timg;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexLevelParameteriv called in begin/end");
+ return;
+ }
+
+ if (level < 0 || level > t->maxLevel)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
+ "glGetTexLevelParameteriv: Invalid level: %d", level);
+ return;
+ }
+
+ crStateGetTextureObjectAndImage(g, target, level, &tobj, &timg);
+ if (!timg)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "GetTexLevelParameteriv: invalid target: 0x%x",
+ target);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WIDTH:
+ *params = (GLint) timg->width;
+ break;
+ case GL_TEXTURE_HEIGHT:
+ *params = (GLint) timg->height;
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_DEPTH:
+ *params = (GLint) timg->depth;
+ break;
+#endif
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ *params = (GLint) timg->internalFormat;
+ break;
+ case GL_TEXTURE_BORDER:
+ *params = (GLint) timg->border;
+ break;
+ case GL_TEXTURE_RED_SIZE:
+ *params = (GLint) timg->texFormat->redbits;
+ break;
+ case GL_TEXTURE_GREEN_SIZE:
+ *params = (GLint) timg->texFormat->greenbits;
+ break;
+ case GL_TEXTURE_BLUE_SIZE:
+ *params = (GLint) timg->texFormat->bluebits;
+ break;
+ case GL_TEXTURE_ALPHA_SIZE:
+ *params = (GLint) timg->texFormat->alphabits;
+ break;
+ case GL_TEXTURE_INTENSITY_SIZE:
+ *params = (GLint) timg->texFormat->intensitybits;
+ break;
+ case GL_TEXTURE_LUMINANCE_SIZE:
+ *params = (GLint) timg->texFormat->luminancebits;
+ break;
+
+#if 0
+ /* XXX TODO */
+ case GL_TEXTURE_DEPTH_SIZE:
+ *params = (GLint) timg->texFormat->depthSize;
+ break;
+#endif
+#if CR_ARB_texture_compression
+ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:
+ *params = (GLint) timg->bytes;
+ break;
+ case GL_TEXTURE_COMPRESSED_ARB:
+ *params = (GLint) timg->compressed;
+ break;
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "GetTexLevelParameteriv: invalid pname: 0x%x",
+ pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+ CRTextureLevel *tl;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexParameterfv called in begin/end");
+ return;
+ }
+
+ crStateGetTextureObjectAndImage(g, target, 0, &tobj, &tl);
+ if (!tobj)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameterfv: invalid target: 0x%x", target);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = (GLfloat) tobj->magFilter;
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = (GLfloat) tobj->minFilter;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = (GLfloat) tobj->wrapS;
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = (GLfloat) tobj->wrapT;
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_WRAP_R:
+ *params = (GLfloat) tobj->wrapR;
+ break;
+ case GL_TEXTURE_PRIORITY:
+ *params = (GLfloat) tobj->priority;
+ break;
+#endif
+ case GL_TEXTURE_BORDER_COLOR:
+ params[0] = tobj->borderColor.r;
+ params[1] = tobj->borderColor.g;
+ params[2] = tobj->borderColor.b;
+ params[3] = tobj->borderColor.a;
+ break;
+#ifdef CR_EXT_texture_filter_anisotropic
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (g->extensions.EXT_texture_filter_anisotropic) {
+ *params = (GLfloat) tobj->maxAnisotropy;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameterfv: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_depth_texture
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (g->extensions.ARB_depth_texture) {
+ *params = (GLfloat) tobj->depthMode;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (g->extensions.ARB_shadow) {
+ *params = (GLfloat) tobj->compareMode;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (g->extensions.ARB_shadow) {
+ *params = (GLfloat) tobj->compareFunc;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow_ambient
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (g->extensions.ARB_shadow_ambient) {
+ *params = (GLfloat) tobj->compareFailValue;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_SGIS_generate_mipmap
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (g->extensions.SGIS_generate_mipmap) {
+ *params = (GLfloat) tobj->generateMipmap;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_MIN_LOD:
+ *params = (GLfloat) tobj->minLod;
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ *params = (GLfloat) tobj->maxLod;
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = (GLfloat) tobj->baseLevel;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = (GLfloat) tobj->maxLevel;
+ break;
+#endif
+#if 0
+ case GL_TEXTURE_LOD_BIAS_EXT:
+ /* XXX todo */
+ *params = (GLfloat) tobj->lodBias;
+ break;
+#endif
+ case GL_TEXTURE_RESIDENT:
+ /* XXX todo */
+ crWarning("glGetTexParameterfv GL_TEXTURE_RESIDENT is unimplemented");
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameterfv: invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStateGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+ CRTextureLevel *tl;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetTexParameter called in begin/end");
+ return;
+ }
+
+ crStateGetTextureObjectAndImage(g, target, 0, &tobj, &tl);
+ if (!tobj)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameteriv: invalid target: 0x%x", target);
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = (GLint) tobj->magFilter;
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = (GLint) tobj->minFilter;
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = (GLint) tobj->wrapS;
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = (GLint) tobj->wrapT;
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_WRAP_R:
+ *params = (GLint) tobj->wrapR;
+ break;
+ case GL_TEXTURE_PRIORITY:
+ *params = (GLint) tobj->priority;
+ break;
+#endif
+ case GL_TEXTURE_BORDER_COLOR:
+ params[0] = (GLint) (tobj->borderColor.r * CR_MAXINT);
+ params[1] = (GLint) (tobj->borderColor.g * CR_MAXINT);
+ params[2] = (GLint) (tobj->borderColor.b * CR_MAXINT);
+ params[3] = (GLint) (tobj->borderColor.a * CR_MAXINT);
+ break;
+#ifdef CR_OPENGL_VERSION_1_2
+ case GL_TEXTURE_MIN_LOD:
+ *params = (GLint) tobj->minLod;
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ *params = (GLint) tobj->maxLod;
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = (GLint) tobj->baseLevel;
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = (GLint) tobj->maxLevel;
+ break;
+#endif
+#ifdef CR_EXT_texture_filter_anisotropic
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (g->extensions.EXT_texture_filter_anisotropic) {
+ *params = (GLint) tobj->maxAnisotropy;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_depth_texture
+ case GL_DEPTH_TEXTURE_MODE_ARB:
+ if (g->extensions.ARB_depth_texture) {
+ *params = (GLint) tobj->depthMode;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow
+ case GL_TEXTURE_COMPARE_MODE_ARB:
+ if (g->extensions.ARB_shadow) {
+ *params = (GLint) tobj->compareMode;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+ case GL_TEXTURE_COMPARE_FUNC_ARB:
+ if (g->extensions.ARB_shadow) {
+ *params = (GLint) tobj->compareFunc;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_ARB_shadow_ambient
+ case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
+ if (g->extensions.ARB_shadow_ambient) {
+ *params = (GLint) tobj->compareFailValue;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+#ifdef CR_SGIS_generate_mipmap
+ case GL_GENERATE_MIPMAP_SGIS:
+ if (g->extensions.SGIS_generate_mipmap) {
+ *params = (GLint) tobj->generateMipmap;
+ }
+ else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: 0x%x", pname);
+ return;
+ }
+ break;
+#endif
+ case GL_TEXTURE_RESIDENT:
+ /* XXX todo */
+ crWarning("glGetTexParameteriv GL_TEXTURE_RESIDENT is unimplemented");
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetTexParameter: invalid pname: %d", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY
+crStatePrioritizeTextures(GLsizei n, const GLuint *textures,
+ const GLclampf *priorities)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+ GLsizei i;
+ UNUSED(priorities);
+
+ for (i = 0; i < n; ++i)
+ {
+ GLuint tex = textures[i];
+ GET_TOBJ(tobj, g, tex);
+ if (!tobj)
+ {
+ Assert(crHashtableIsKeyUsed(g->shared->textureTable, tex));
+ tobj = crStateTextureAllocate_t(g, tex);
+ }
+
+ /* so far the code just ensures the tex object is created to make
+ * the crserverlib code be able to pass it to host ogl */
+
+ /** @todo store texture priorities in the state data to be able to restore it properly
+ * on save state load */
+ }
+
+ return;
+}
+
+
+GLboolean STATE_APIENTRY
+crStateAreTexturesResident(GLsizei n, const GLuint *textures,
+ GLboolean *residences)
+{
+ UNUSED(n);
+ UNUSED(textures);
+ UNUSED(residences);
+ /** @todo */
+ return GL_TRUE;
+}
+
+
+GLboolean STATE_APIENTRY
+crStateIsTexture(GLuint texture)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+
+ GET_TOBJ(tobj, g, texture);
+ return tobj != NULL;
+}
+
+static void crStateCheckTextureHWIDCB(unsigned long key, void *data1, void *data2)
+{
+ CRTextureObj *pTex = (CRTextureObj *) data1;
+ crCheckIDHWID_t *pParms = (crCheckIDHWID_t*) data2;
+ (void) key;
+
+ if (crStateGetTextureObjHWID(pTex)==pParms->hwid)
+ pParms->id = pTex->id;
+}
+
+DECLEXPORT(GLuint) STATE_APIENTRY crStateTextureHWIDtoID(GLuint hwid)
+{
+ CRContext *g = GetCurrentContext();
+ crCheckIDHWID_t parms;
+
+ parms.id = hwid;
+ parms.hwid = hwid;
+
+ crHashtableWalk(g->shared->textureTable, crStateCheckTextureHWIDCB, &parms);
+ return parms.id;
+}
+
+DECLEXPORT(GLuint) STATE_APIENTRY crStateGetTextureHWID(GLuint id)
+{
+ CRContext *g = GetCurrentContext();
+ CRTextureObj *tobj;
+
+ GET_TOBJ(tobj, g, id);
+
+#ifdef DEBUG_misha
+ if (id)
+ {
+ Assert(tobj);
+ }
+ else
+ {
+ Assert(!tobj);
+ }
+ if (tobj)
+ {
+/* crDebug("tex id(%d), hwid(%d)", tobj->id, tobj->hwid);*/
+ }
+#endif
+
+
+ return tobj ? crStateGetTextureObjHWID(tobj) : 0;
+}
+
+DECLEXPORT(GLuint) STATE_APIENTRY crStateGetTextureObjHWID(CRTextureObj *tobj)
+{
+ CRASSERT(tobj);
+
+#ifndef IN_GUEST
+ if (tobj->id && !tobj->hwid)
+ {
+ CRASSERT(diff_api.GenTextures);
+ diff_api.GenTextures(1, &tobj->hwid);
+#if 0 /*def DEBUG_misha*/
+ crDebug("tex id(%d), hwid(%d)", tobj->id, tobj->hwid);
+#endif
+ CRASSERT(tobj->hwid);
+ }
+#endif
+
+ return tobj->hwid;
+}