/* Copyright (c) 2001, Stanford University * All rights reserved * * See the file LICENSE.txt for information on redistributing this software. */ #include #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; ilight + 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, ¶m ); } 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, ¶m ); } 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]; /* FALLTHROUGH! */ 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]; /* FALLTHROUGH! */ 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; } /* FALLTHROUGH! */ 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]; /* FALLTHROUGH! */ 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]; /* FALLTHROUGH! */ 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]; /* FALLTHROUGH! */ 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; /* FALLTHROUGH! */ 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]; /* FALLTHROUGH! */ 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, ¶m ); } 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]) ); } }