summaryrefslogtreecommitdiffstats
path: root/src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c')
-rw-r--r--src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c1212
1 files changed, 1212 insertions, 0 deletions
diff --git a/src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c b/src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c
new file mode 100644
index 00000000..bfea8559
--- /dev/null
+++ b/src/VBox/GuestHost/OpenGL/state_tracker/state_lighting.c
@@ -0,0 +1,1212 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include "state.h"
+#include "cr_mem.h"
+#include "state/cr_statetypes.h"
+#include "state_internals.h"
+
+void crStateLightingInitBits (CRLightingBits *l)
+{
+ l->light = (CRLightBits *) crCalloc (sizeof(*(l->light)) * CR_MAX_LIGHTS);
+}
+
+void crStateLightingDestroyBits (CRLightingBits *l)
+{
+ crFree(l->light);
+}
+
+void crStateLightingDestroy (CRContext *ctx)
+{
+ crFree(ctx->lighting.light);
+}
+
+void crStateLightingInit (CRContext *ctx)
+{
+ CRLightingState *l = &ctx->lighting;
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+ int i;
+ GLvectorf zero_vector = {0.0f, 0.0f, 0.0f, 1.0f};
+ GLcolorf zero_color = {0.0f, 0.0f, 0.0f, 1.0f};
+ GLcolorf ambient_color = {0.2f, 0.2f, 0.2f, 1.0f};
+ GLcolorf diffuse_color = {0.8f, 0.8f, 0.8f, 1.0f};
+ GLvectorf spot_vector = {0.0f, 0.0f, -1.0f, 0.0f};
+ GLcolorf one_color = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ l->lighting = GL_FALSE;
+ RESET(lb->enable, ctx->bitid);
+ l->colorMaterial = GL_FALSE;
+ RESET(lb->colorMaterial, ctx->bitid);
+ l->shadeModel = GL_SMOOTH;
+ RESET(lb->shadeModel, ctx->bitid);
+ l->colorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
+ l->colorMaterialFace = GL_FRONT_AND_BACK;
+ l->ambient[0] = ambient_color;
+ l->diffuse[0] = diffuse_color;
+ l->specular[0] = zero_color;
+ l->emission[0] = zero_color;
+ l->shininess[0] = 0.0f;
+ l->indexes[0][0] = 0;
+ l->indexes[0][1] = 1;
+ l->indexes[0][2] = 1;
+ l->ambient[1] = ambient_color;
+ l->diffuse[1] = diffuse_color;
+ l->specular[1] = zero_color;
+ l->emission[1] = zero_color;
+ l->shininess[1] = 0.0f;
+ l->indexes[1][0] = 0;
+ l->indexes[1][1] = 1;
+ l->indexes[1][2] = 1;
+ RESET(lb->material, ctx->bitid);
+ l->lightModelAmbient = ambient_color;
+ l->lightModelLocalViewer = GL_FALSE;
+ l->lightModelTwoSide = GL_FALSE;
+#if defined(CR_EXT_separate_specular_color)
+ l->lightModelColorControlEXT = GL_SINGLE_COLOR_EXT;
+#elif defined(CR_OPENGL_VERSION_1_2)
+ l->lightModelColorControlEXT = GL_SINGLE_COLOR;
+#endif
+ RESET(lb->lightModel, ctx->bitid);
+#if defined(CR_EXT_secondary_color)
+ l->colorSumEXT = GL_FALSE;
+#endif
+ l->light = (CRLight *) crCalloc (sizeof (*(l->light)) * CR_MAX_LIGHTS);
+
+ for (i=0; i<CR_MAX_LIGHTS; i++)
+ {
+ CRLightBits *ltb = lb->light + i;
+ l->light[i].enable = GL_FALSE;
+ RESET(ltb->enable, ctx->bitid);
+ l->light[i].ambient = zero_color;
+ RESET(ltb->ambient, ctx->bitid);
+ l->light[i].diffuse = zero_color;
+ RESET(ltb->diffuse, ctx->bitid);
+ l->light[i].specular = zero_color;
+ RESET(ltb->specular, ctx->bitid);
+ l->light[i].position = zero_vector;
+ l->light[i].position.z = 1.0f;
+ l->light[i].position.w = 0.0f;
+ l->light[i].objPosition = l->light[i].position;
+ RESET(ltb->position, ctx->bitid);
+ l->light[i].spotDirection = spot_vector;
+ l->light[i].spotExponent = 0.0f;
+ l->light[i].spotCutoff = 180.0f;
+ RESET(ltb->spot, ctx->bitid);
+ l->light[i].constantAttenuation= 1.0f;
+ l->light[i].linearAttenuation= 0.0f;
+ l->light[i].quadraticAttenuation = 0.0f;
+ RESET(ltb->attenuation, ctx->bitid);
+ RESET(ltb->dirty, ctx->bitid);
+ }
+ l->light[0].diffuse = one_color;
+ l->light[0].specular = one_color;
+
+ RESET(lb->dirty, ctx->bitid);
+}
+
+void STATE_APIENTRY crStateShadeModel (GLenum mode)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "ShadeModel called in begin/end");
+ return;
+ }
+
+ FLUSH();
+
+ if (mode != GL_SMOOTH &&
+ mode != GL_FLAT)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "ShadeModel: Bogus mode 0x%x", mode);
+ return;
+ }
+
+ l->shadeModel = mode;
+ DIRTY(lb->shadeModel, g->neg_bitid);
+ DIRTY(lb->dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateColorMaterial (GLenum face, GLenum mode)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "ColorMaterial called in begin/end");
+ return;
+ }
+
+ FLUSH();
+
+ if (face != GL_FRONT &&
+ face != GL_BACK &&
+ face != GL_FRONT_AND_BACK)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "ColorMaterial: Bogus face &d", face);
+ return;
+ }
+
+ if (mode != GL_EMISSION &&
+ mode != GL_AMBIENT &&
+ mode != GL_DIFFUSE &&
+ mode != GL_SPECULAR &&
+ mode != GL_AMBIENT_AND_DIFFUSE)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "ColorMaterial: Bogus mode &d", mode);
+ return;
+ }
+
+ l->colorMaterialFace = face;
+ l->colorMaterialMode = mode;
+ /* XXX this could conceivably be needed here (BP) */
+ /*
+ crStateColorMaterialRecover();
+ */
+ DIRTY(lb->colorMaterial, g->neg_bitid);
+ DIRTY(lb->dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateLightModelfv (GLenum pname, const GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "LightModelfv called in begin/end");
+ return;
+ }
+
+ FLUSH();
+
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ l->lightModelLocalViewer = (GLboolean) (*param==0.0f?GL_FALSE:GL_TRUE);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ l->lightModelTwoSide = (GLboolean) (*param==0.0f?GL_FALSE:GL_TRUE);
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ l->lightModelAmbient.r = param[0];
+ l->lightModelAmbient.g = param[1];
+ l->lightModelAmbient.b = param[2];
+ l->lightModelAmbient.a = param[3];
+ break;
+#if defined(CR_OPENGL_VERSION_1_2)
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ if (param[0] == GL_SEPARATE_SPECULAR_COLOR || param[0] == GL_SINGLE_COLOR)
+ {
+ l->lightModelColorControlEXT = (GLenum) param[0];
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModel: Invalid param for LIGHT_MODEL_COLOR_CONTROL: 0x%x", param[0]);
+ return;
+ }
+ break;
+#else
+#if defined(CR_EXT_separate_specular_color)
+ case GL_LIGHT_MODEL_COLOR_CONTROL_EXT:
+ if(g->extensions.EXT_separate_specular_color)
+ {
+ if (param[0] == GL_SEPARATE_SPECULAR_COLOR_EXT || param[0] == GL_SINGLE_COLOR_EXT)
+ {
+ l->lightModelColorControlEXT = (GLenum) param[0];
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModel: Invalid param for LIGHT_MODEL_COLOR_CONTROL: 0x%x", param[0]);
+ return;
+ }
+ }
+ else
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModel( LIGHT_MODEL_COLOR_CONTROL, ...) - EXT_separate_specular_color is unavailable.");
+ return;
+ }
+ break;
+#endif
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModelfv: Invalid pname: 0x%x", pname);
+ return;
+ }
+ DIRTY(lb->lightModel, g->neg_bitid);
+ DIRTY(lb->dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateLightModeliv (GLenum pname, const GLint *param)
+{
+ GLfloat f_param;
+ GLcolor f_color;
+#ifndef CR_OPENGL_VERSION_1_2
+ CRContext *g = GetCurrentContext();
+#endif
+
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ f_param = (GLfloat) (*param);
+ crStateLightModelfv(pname, &f_param);
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ 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;
+ crStateLightModelfv(pname, (GLfloat *) &f_color);
+ break;
+#if defined(CR_OPENGL_VERSION_1_2)
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ f_param = (GLfloat) (*param);
+ crStateLightModelfv(pname, &f_param);
+ break;
+#else
+#ifdef CR_EXT_separate_specular_color
+ case GL_LIGHT_MODEL_COLOR_CONTROL_EXT:
+ if (g->extensions.EXT_separate_specular_color) {
+ f_param = (GLfloat) (*param);
+ crStateLightModelfv(pname, &f_param);
+ } else {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModeliv(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, ...) - EXT_separate_specular_color not enabled!");
+ return;
+ }
+ break;
+#endif
+#endif
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "LightModeliv: Invalid pname: 0x%x", pname);
+ return;
+ }
+}
+
+void STATE_APIENTRY crStateLightModelf (GLenum pname, GLfloat param)
+{
+ crStateLightModelfv(pname, &param);
+}
+
+void STATE_APIENTRY crStateLightModeli (GLenum pname, GLint param)
+{
+ GLfloat f_param = (GLfloat) param;
+ crStateLightModelfv(pname, &f_param);
+}
+
+void STATE_APIENTRY crStateLightfv (GLenum light, GLenum pname, const GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRTransformState *t = &(g->transform);
+ CRLight *lt;
+ unsigned int i;
+ GLfloat x, y, z, w;
+ CRmatrix inv;
+ CRmatrix *mat;
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+ CRLightBits *ltb;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glLightfv called in begin/end");
+ return;
+ }
+
+ FLUSH();
+
+ i = light - GL_LIGHT0;
+ if (i>=g->limits.maxLights)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glLight: invalid light specified: 0x%x", light);
+ return;
+ }
+
+ lt = l->light + i;
+ ltb = lb->light + i;
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ lt->ambient.r = param[0];
+ lt->ambient.g = param[1];
+ lt->ambient.b = param[2];
+ lt->ambient.a = param[3];
+ DIRTY(ltb->ambient, g->neg_bitid);
+ break;
+ case GL_DIFFUSE:
+ lt->diffuse.r = param[0];
+ lt->diffuse.g = param[1];
+ lt->diffuse.b = param[2];
+ lt->diffuse.a = param[3];
+ DIRTY(ltb->diffuse, g->neg_bitid);
+ break;
+ case GL_SPECULAR:
+ lt->specular.r = param[0];
+ lt->specular.g = param[1];
+ lt->specular.b = param[2];
+ lt->specular.a = param[3];
+ DIRTY(ltb->specular, g->neg_bitid);
+ break;
+ case GL_POSITION:
+ x = param[0];
+ y = param[1];
+ z = param[2];
+ w = param[3];
+ mat = t->modelViewStack.top;
+ lt->objPosition.x = x;
+ lt->objPosition.y = y;
+ lt->objPosition.z = z;
+ lt->objPosition.w = w;
+
+ lt->position.x = mat->m00*x + mat->m10*y + mat->m20*z + mat->m30*w;
+ lt->position.y = mat->m01*x + mat->m11*y + mat->m21*z + mat->m31*w;
+ lt->position.z = mat->m02*x + mat->m12*y + mat->m22*z + mat->m32*w;
+ lt->position.w = mat->m03*x + mat->m13*y + mat->m23*z + mat->m33*w;
+
+ DIRTY(ltb->position, g->neg_bitid);
+ break;
+ case GL_SPOT_DIRECTION:
+ lt->spotDirection.x = param[0];
+ lt->spotDirection.y = param[1];
+ lt->spotDirection.z = param[2];
+ lt->spotDirection.w = 0.0f;
+ mat = t->modelViewStack.top;
+
+ if (lt->objPosition.w != 0.0f)
+ {
+ lt->spotDirection.w = - ( ( lt->objPosition.x * lt->spotDirection.x +
+ lt->objPosition.y * lt->spotDirection.y +
+ lt->objPosition.z * lt->spotDirection.z ) /
+ lt->objPosition.w );
+ }
+
+ crMatrixInvertTranspose(&inv, mat);
+ crStateTransformXformPointMatrixf (&inv, &(lt->spotDirection));
+
+ DIRTY(ltb->spot, g->neg_bitid);
+ break;
+ case GL_SPOT_EXPONENT:
+ if (*param < 0.0f || *param > 180.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLight: spot exponent out of range: %f", *param);
+ return;
+ }
+ lt->spotExponent = *param;
+ DIRTY(ltb->spot, g->neg_bitid);
+ break;
+ case GL_SPOT_CUTOFF:
+ if ((*param < 0.0f || *param > 90.0f) && *param != 180.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLight: spot cutoff out of range: %f", *param);
+ return;
+ }
+ lt->spotCutoff = *param;
+ DIRTY(ltb->spot, g->neg_bitid);
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ if (*param < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLight: constant Attenuation negative: %f", *param);
+ return;
+ }
+ lt->constantAttenuation = *param;
+ DIRTY(ltb->attenuation, g->neg_bitid);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ if (*param < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLight: linear Attenuation negative: %f", *param);
+ return;
+ }
+ lt->linearAttenuation = *param;
+ DIRTY(ltb->attenuation, g->neg_bitid);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ if (*param < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLight: quadratic Attenuation negative: %f", *param);
+ return;
+ }
+ lt->quadraticAttenuation = *param;
+ DIRTY(ltb->attenuation, g->neg_bitid);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glLight: invalid pname: 0x%x", pname);
+ return;
+ }
+ DIRTY(ltb->dirty, g->neg_bitid);
+ DIRTY(lb->dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateLightiv (GLenum light, GLenum pname, const GLint *param)
+{
+ GLfloat f_param;
+ GLcolor f_color;
+ GLvector f_vector;
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ case GL_DIFFUSE:
+ case GL_SPECULAR:
+ 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;
+ crStateLightfv(light, pname, (GLfloat *) &f_color);
+ break;
+ case GL_POSITION:
+ case GL_SPOT_DIRECTION:
+ f_vector.x = (GLfloat) param[0];
+ f_vector.y = (GLfloat) param[1];
+ f_vector.z = (GLfloat) param[2];
+ f_vector.w = (GLfloat) param[3];
+ crStateLightfv(light, pname, (GLfloat *) &f_vector);
+ break;
+ case GL_SPOT_EXPONENT:
+ case GL_SPOT_CUTOFF:
+ case GL_CONSTANT_ATTENUATION:
+ case GL_LINEAR_ATTENUATION:
+ case GL_QUADRATIC_ATTENUATION:
+ f_param = (GLfloat) (*param);
+ crStateLightfv(light, pname, &f_param);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glLight: invalid pname: 0x%x", pname);
+ return;
+ }
+}
+
+void STATE_APIENTRY crStateLightf (GLenum light, GLenum pname, GLfloat param)
+{
+ crStateLightfv(light, pname, &param);
+}
+
+void STATE_APIENTRY crStateLighti (GLenum light, GLenum pname, GLint param)
+{
+ GLfloat f_param = (GLfloat) param;
+ crStateLightfv(light, pname, &f_param);
+}
+
+void STATE_APIENTRY crStateMaterialfv (GLenum face, GLenum pname, const GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRStateBits *sb = GetCurrentBits();
+ CRLightingBits *lb = &(sb->lighting);
+
+ if (!g->current.inBeginEnd)
+ {
+ FLUSH();
+ }
+
+ switch (pname)
+ {
+ case GL_AMBIENT :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->ambient[0].r = param[0];
+ l->ambient[0].g = param[1];
+ l->ambient[0].b = param[2];
+ l->ambient[0].a = param[3];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->ambient[0].r = param[0];
+ l->ambient[0].g = param[1];
+ l->ambient[0].b = param[2];
+ l->ambient[0].a = param[3];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->ambient[1].r = param[0];
+ l->ambient[1].g = param[1];
+ l->ambient[1].b = param[2];
+ l->ambient[1].a = param[3];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_AMBIENT_AND_DIFFUSE :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->ambient[0].r = param[0];
+ l->ambient[0].g = param[1];
+ l->ambient[0].b = param[2];
+ l->ambient[0].a = param[3];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->ambient[0].r = param[0];
+ l->ambient[0].g = param[1];
+ l->ambient[0].b = param[2];
+ l->ambient[0].a = param[3];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->ambient[1].r = param[0];
+ l->ambient[1].g = param[1];
+ l->ambient[1].b = param[2];
+ l->ambient[1].a = param[3];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ RT_FALL_THRU();
+ case GL_DIFFUSE :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->diffuse[0].r = param[0];
+ l->diffuse[0].g = param[1];
+ l->diffuse[0].b = param[2];
+ l->diffuse[0].a = param[3];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->diffuse[0].r = param[0];
+ l->diffuse[0].g = param[1];
+ l->diffuse[0].b = param[2];
+ l->diffuse[0].a = param[3];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->diffuse[1].r = param[0];
+ l->diffuse[1].g = param[1];
+ l->diffuse[1].b = param[2];
+ l->diffuse[1].a = param[3];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SPECULAR :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->specular[0].r = param[0];
+ l->specular[0].g = param[1];
+ l->specular[0].b = param[2];
+ l->specular[0].a = param[3];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->specular[0].r = param[0];
+ l->specular[0].g = param[1];
+ l->specular[0].b = param[2];
+ l->specular[0].a = param[3];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->specular[1].r = param[0];
+ l->specular[1].g = param[1];
+ l->specular[1].b = param[2];
+ l->specular[1].a = param[3];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_EMISSION :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->emission[0].r = param[0];
+ l->emission[0].g = param[1];
+ l->emission[0].b = param[2];
+ l->emission[0].a = param[3];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->emission[0].r = param[0];
+ l->emission[0].g = param[1];
+ l->emission[0].b = param[2];
+ l->emission[0].a = param[3];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->emission[1].r = param[0];
+ l->emission[1].g = param[1];
+ l->emission[1].b = param[2];
+ l->emission[1].a = param[3];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SHININESS:
+ if (*param > 180.0f || *param < 0.0f)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glMaterialfv: param out of range: %f", param);
+ return;
+ }
+
+ switch (face)
+ {
+ case GL_FRONT:
+ l->shininess[0] = *param;
+ break;
+ case GL_FRONT_AND_BACK:
+ l->shininess[0] = *param;
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->shininess[1] = *param;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_COLOR_INDEXES :
+ switch (face)
+ {
+ case GL_FRONT:
+ l->indexes[0][0] = (GLint) param[0];
+ l->indexes[0][1] = (GLint) param[1];
+ l->indexes[0][2] = (GLint) param[2];
+ break;
+ case GL_FRONT_AND_BACK:
+ l->indexes[0][0] = (GLint) param[0];
+ l->indexes[0][1] = (GLint) param[1];
+ l->indexes[0][2] = (GLint) param[2];
+ RT_FALL_THRU();
+ case GL_BACK:
+ l->indexes[1][0] = (GLint) param[0];
+ l->indexes[1][1] = (GLint) param[1];
+ l->indexes[1][2] = (GLint) param[2];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialfv: bad pname: 0x%x", pname);
+ return;
+ }
+ DIRTY(lb->material, g->neg_bitid);
+ DIRTY(lb->dirty, g->neg_bitid);
+}
+
+void STATE_APIENTRY crStateMaterialiv (GLenum face, GLenum pname, const GLint *param)
+{
+ GLfloat f_param;
+ GLcolor f_color;
+
+ switch (pname)
+ {
+ case GL_AMBIENT :
+ case GL_AMBIENT_AND_DIFFUSE :
+ case GL_DIFFUSE :
+ case GL_SPECULAR :
+ case GL_EMISSION :
+ f_color.r = ((GLfloat) param[0]) / ((GLfloat) CR_MAXINT);
+ f_color.g = ((GLfloat) param[1]) / ((GLfloat) CR_MAXINT);
+ f_color.b = ((GLfloat) param[2]) / ((GLfloat) CR_MAXINT);
+ f_color.a = ((GLfloat) param[3]) / ((GLfloat) CR_MAXINT);
+ crStateMaterialfv(face, pname, (GLfloat *) &f_color);
+ break;
+ case GL_SHININESS:
+ f_param = (GLfloat) (*param);
+ crStateMaterialfv(face, pname, (GLfloat *) &f_param);
+ break;
+ case GL_COLOR_INDEXES :
+ f_param = (GLfloat) (*param);
+ crStateMaterialfv(face, pname, (GLfloat *) &f_param);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glMaterialiv: bad pname: 0x%x", pname);
+ return;
+ }
+}
+
+void STATE_APIENTRY crStateMaterialf (GLenum face, GLenum pname, GLfloat param)
+{
+ crStateMaterialfv(face, pname, &param);
+}
+
+void STATE_APIENTRY crStateMateriali (GLenum face, GLenum pname, GLint param)
+{
+ GLfloat f_param = (GLfloat) param;
+ crStateMaterialfv(face, pname, &f_param);
+}
+
+void STATE_APIENTRY crStateGetLightfv (GLenum light, GLenum pname, GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRLight *lt;
+ unsigned int i;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetLightfv called in begin/end");
+ return;
+ }
+
+ i = light - GL_LIGHT0;
+ if (i>=g->limits.maxLights)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetLight: invalid light specified: 0x%x", light);
+ return;
+ }
+
+ lt = l->light + i;
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ param[0] = lt->ambient.r;
+ param[1] = lt->ambient.g;
+ param[2] = lt->ambient.b;
+ param[3] = lt->ambient.a;
+ break;
+ case GL_DIFFUSE:
+ param[0] = lt->diffuse.r;
+ param[1] = lt->diffuse.g;
+ param[2] = lt->diffuse.b;
+ param[3] = lt->diffuse.a;
+ break;
+ case GL_SPECULAR:
+ param[0] = lt->specular.r;
+ param[1] = lt->specular.g;
+ param[2] = lt->specular.b;
+ param[3] = lt->specular.a;
+ break;
+ case GL_POSITION:
+ param[0] = lt->position.x;
+ param[1] = lt->position.y;
+ param[2] = lt->position.z;
+ param[3] = lt->position.w;
+ break;
+ case GL_SPOT_DIRECTION:
+ param[0] = lt->spotDirection.x;
+ param[1] = lt->spotDirection.y;
+ param[2] = lt->spotDirection.z;
+#if 0
+ /* the w-component of the direction, although possibly (?)
+ useful to keep around internally, is not returned as part
+ of the get. */
+ param[3] = lt->spotDirection.w;
+#endif
+ break;
+ case GL_SPOT_EXPONENT:
+ *param = lt->spotExponent;
+ break;
+ case GL_SPOT_CUTOFF:
+ *param = lt->spotCutoff;
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ *param = lt->constantAttenuation;
+ break;
+ case GL_LINEAR_ATTENUATION:
+ *param = lt->linearAttenuation;
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ *param = lt->quadraticAttenuation;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetLight: invalid pname: 0x%x", pname);
+ return;
+ }
+}
+
+void STATE_APIENTRY crStateGetLightiv (GLenum light, GLenum pname, GLint *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRLight *lt;
+ unsigned int i;
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetLightiv called in begin/end");
+ return;
+ }
+
+ i = light - GL_LIGHT0;
+ if (i>=g->limits.maxLights)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetLight: invalid light specified: 0x%x", light);
+ return;
+ }
+
+ lt = l->light + i;
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ param[0] = (GLint) (lt->ambient.r * CR_MAXINT);
+ param[1] = (GLint) (lt->ambient.g * CR_MAXINT);
+ param[2] = (GLint) (lt->ambient.b * CR_MAXINT);
+ param[3] = (GLint) (lt->ambient.a * CR_MAXINT);
+ break;
+ case GL_DIFFUSE:
+ param[0] = (GLint) (lt->diffuse.r * CR_MAXINT);
+ param[1] = (GLint) (lt->diffuse.g * CR_MAXINT);
+ param[2] = (GLint) (lt->diffuse.b * CR_MAXINT);
+ param[3] = (GLint) (lt->diffuse.a * CR_MAXINT);
+ break;
+ case GL_SPECULAR:
+ param[0] = (GLint) (lt->specular.r * CR_MAXINT);
+ param[1] = (GLint) (lt->specular.g * CR_MAXINT);
+ param[2] = (GLint) (lt->specular.b * CR_MAXINT);
+ param[3] = (GLint) (lt->specular.a * CR_MAXINT);
+ break;
+ case GL_POSITION:
+ param[0] = (GLint) (lt->position.x);
+ param[1] = (GLint) (lt->position.y);
+ param[2] = (GLint) (lt->position.z);
+ param[3] = (GLint) (lt->position.w);
+ break;
+ case GL_SPOT_DIRECTION:
+ param[0] = (GLint) (lt->spotDirection.x);
+ param[1] = (GLint) (lt->spotDirection.y);
+ param[2] = (GLint) (lt->spotDirection.z);
+#if 0
+ /* the w-component of the direction, although possibly (?)
+ useful to keep around internally, is not returned as part
+ of the get. */
+ param[3] = (GLint) (lt->spotDirection.w);
+#endif
+ break;
+ case GL_SPOT_EXPONENT:
+ *param = (GLint) (lt->spotExponent);
+ break;
+ case GL_SPOT_CUTOFF:
+ *param = (GLint) (lt->spotCutoff);
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ *param = (GLint) (lt->constantAttenuation);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ *param = (GLint) (lt->linearAttenuation);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ *param = (GLint) (lt->quadraticAttenuation);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetLight: invalid pname: 0x%x", pname);
+ return;
+ }
+}
+
+void STATE_APIENTRY crStateGetMaterialfv (GLenum face, GLenum pname, GLfloat *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetMaterialfv called in begin/end");
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = l->ambient[0].r;
+ param[1] = l->ambient[0].g;
+ param[2] = l->ambient[0].b;
+ param[3] = l->ambient[0].a;
+ break;
+ case GL_BACK:
+ param[0] = l->ambient[1].r;
+ param[1] = l->ambient[1].g;
+ param[2] = l->ambient[1].b;
+ param[3] = l->ambient[1].a;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_DIFFUSE:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = l->diffuse[0].r;
+ param[1] = l->diffuse[0].g;
+ param[2] = l->diffuse[0].b;
+ param[3] = l->diffuse[0].a;
+ break;
+ case GL_BACK:
+ param[0] = l->diffuse[1].r;
+ param[1] = l->diffuse[1].g;
+ param[2] = l->diffuse[1].b;
+ param[3] = l->diffuse[1].a;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SPECULAR :
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = l->specular[0].r;
+ param[1] = l->specular[0].g;
+ param[2] = l->specular[0].b;
+ param[3] = l->specular[0].a;
+ break;
+ case GL_BACK:
+ param[0] = l->specular[1].r;
+ param[1] = l->specular[1].g;
+ param[2] = l->specular[1].b;
+ param[3] = l->specular[1].a;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_EMISSION:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = l->emission[0].r;
+ param[1] = l->emission[0].g;
+ param[2] = l->emission[0].b;
+ param[3] = l->emission[0].a;
+ break;
+ case GL_BACK:
+ param[0] = l->emission[1].r;
+ param[1] = l->emission[1].g;
+ param[2] = l->emission[1].b;
+ param[3] = l->emission[1].a;
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SHININESS:
+ switch (face)
+ {
+ case GL_FRONT:
+ *param = l->shininess[0];
+ break;
+ case GL_BACK:
+ *param = l->shininess[1];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_COLOR_INDEXES :
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLfloat) l->indexes[0][0];
+ param[1] = (GLfloat) l->indexes[0][1];
+ param[2] = (GLfloat) l->indexes[0][2];
+ break;
+ case GL_BACK:
+ param[0] = (GLfloat) l->indexes[1][0];
+ param[1] = (GLfloat) l->indexes[1][1];
+ param[2] = (GLfloat) l->indexes[1][2];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad face: 0x%x", face);
+ return;
+ }
+ return;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialfv: bad pname: 0x%x", pname);
+ return;
+ }
+}
+
+
+void STATE_APIENTRY crStateGetMaterialiv (GLenum face, GLenum pname, GLint *param)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+
+ if (g->current.inBeginEnd)
+ {
+ crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
+ "glGetMaterialiv called in begin/end");
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_AMBIENT:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLint) (l->ambient[0].r * CR_MAXINT);
+ param[1] = (GLint) (l->ambient[0].g * CR_MAXINT);
+ param[2] = (GLint) (l->ambient[0].b * CR_MAXINT);
+ param[3] = (GLint) (l->ambient[0].a * CR_MAXINT);
+ break;
+ case GL_BACK:
+ param[0] = (GLint) (l->ambient[1].r * CR_MAXINT);
+ param[1] = (GLint) (l->ambient[1].g * CR_MAXINT);
+ param[2] = (GLint) (l->ambient[1].b * CR_MAXINT);
+ param[3] = (GLint) (l->ambient[1].a * CR_MAXINT);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_DIFFUSE:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLint) (l->diffuse[0].r * CR_MAXINT);
+ param[1] = (GLint) (l->diffuse[0].g * CR_MAXINT);
+ param[2] = (GLint) (l->diffuse[0].b * CR_MAXINT);
+ param[3] = (GLint) (l->diffuse[0].a * CR_MAXINT);
+ break;
+ case GL_BACK:
+ param[0] = (GLint) (l->diffuse[1].r * CR_MAXINT);
+ param[1] = (GLint) (l->diffuse[1].g * CR_MAXINT);
+ param[2] = (GLint) (l->diffuse[1].b * CR_MAXINT);
+ param[3] = (GLint) (l->diffuse[1].a * CR_MAXINT);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SPECULAR:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLint) (l->specular[0].r * CR_MAXINT);
+ param[1] = (GLint) (l->specular[0].g * CR_MAXINT);
+ param[2] = (GLint) (l->specular[0].b * CR_MAXINT);
+ param[3] = (GLint) (l->specular[0].a * CR_MAXINT);
+ break;
+ case GL_BACK:
+ param[0] = (GLint) (l->specular[1].r * CR_MAXINT);
+ param[1] = (GLint) (l->specular[1].g * CR_MAXINT);
+ param[2] = (GLint) (l->specular[1].b * CR_MAXINT);
+ param[3] = (GLint) (l->specular[1].a * CR_MAXINT);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_EMISSION:
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLint) (l->emission[0].r * CR_MAXINT);
+ param[1] = (GLint) (l->emission[0].g * CR_MAXINT);
+ param[2] = (GLint) (l->emission[0].b * CR_MAXINT);
+ param[3] = (GLint) (l->emission[0].a * CR_MAXINT);
+ break;
+ case GL_BACK:
+ param[0] = (GLint) (l->emission[1].r * CR_MAXINT);
+ param[1] = (GLint) (l->emission[1].g * CR_MAXINT);
+ param[2] = (GLint) (l->emission[1].b * CR_MAXINT);
+ param[3] = (GLint) (l->emission[1].a * CR_MAXINT);
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_SHININESS:
+ switch (face) {
+ case GL_FRONT:
+ *param = (GLint) l->shininess[0];
+ break;
+ case GL_BACK:
+ *param = (GLint) l->shininess[1];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ break;
+ case GL_COLOR_INDEXES :
+ switch (face)
+ {
+ case GL_FRONT:
+ param[0] = (GLint) l->indexes[0][0];
+ param[1] = (GLint) l->indexes[0][1];
+ param[2] = (GLint) l->indexes[0][2];
+ break;
+ case GL_BACK:
+ param[0] = (GLint) l->indexes[1][0];
+ param[1] = (GLint) l->indexes[1][1];
+ param[2] = (GLint) l->indexes[1][2];
+ break;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad face: 0x%x", face);
+ return;
+ }
+ return;
+ default:
+ crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
+ "glGetMaterialiv: bad pname: 0x%x", pname);
+ return;
+ }
+}
+
+void crStateColorMaterialRecover(void)
+{
+ CRContext *g = GetCurrentContext();
+ CRLightingState *l = &(g->lighting);
+ CRCurrentState *c = &(g->current);
+
+ /* Assuming that the "current" values are up to date,
+ * this function will extract them into the material
+ * values if COLOR_MATERIAL has been enabled on the
+ * client. */
+
+ if (l->colorMaterial)
+ {
+ /* prevent recursion here (was in tilesortspu_flush.c's doFlush() for a
+ * short time. Without this, kirchner_colormaterial fails.
+ */
+ crStateFlushFunc(NULL);
+
+ crStateMaterialfv(l->colorMaterialFace, l->colorMaterialMode, &(c->vertexAttrib[VERT_ATTRIB_COLOR0][0]));
+ }
+}