/* * $Id$ * * $Date$ * $Revision$ * * (C) 1999 by Thomas and Hans-Jörg Frieden * All rights reserved * * This file is part of the MiniGL library project * See the file Licence.txt for more details * */ #include "displaylists.h" #include "sysinc.h" #include #include #include "mgl/gl.h" #include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif extern float CLAMPF(float a); #ifdef MGL_USE_LIGHTING /* These are helpers for computing the lighting formulas */ static inline GLfloat max_dot(MGLDirection *d1, MGLDirection *d2) { GLfloat res = d1->x * d2->x + d1->y * d2->y + d1->z * d2->z; if (res > 0.0) return res; else return 0.0; } #define COLOR_COPY(_r, _c1) \ do \ { \ _r.r = _c1.r; \ _r.g = _c1.g; \ _r.b = _c1.b; \ } while (0) #define COLOR_MULT(_r, _c1, _c2) \ do \ { \ _r.r = _c1.r * _c2.r; \ _r.g = _c1.g * _c2.g; \ _r.b = _c1.b * _c2.b; \ } while (0) #define COLOR_ADD(_r, _c1, _c2) \ do \ { \ _r.r = _c1.r + _c2.r; \ _r.g = _c1.g + _c2.g; \ _r.b = _c1.b + _c2.b; \ } while (0) #define COLOR_MULT_SCALAR(_r, _s, _c1) \ do \ { \ _r.r = _c1.r * _s; \ _r.g = _c1.g * _s; \ _r.b = _c1.b * _s; \ } while (0) #define COLOR_MUL_ACCUM(_r, _c1, _c2) \ do \ { \ _r.r += _c1.r * _c2.r; \ _r.g += _c1.g * _c2.g; \ _r.b += _c1.b * _c2.b; \ } while (0) #define COLOR_ADD_SCALED(_r, _s, _c) \ do \ { \ GLfloat s = _s; \ _r.r += s * _c.r; \ _r.g += s * _c.g; \ _r.b += s * _c.b; \ } while (0) #define COLOR_PRINT(_r) \ do \ { \ kprintf("%s: %f, %f, %f\n", \ #_r, \ _r.r, _r.g, _r.b); \ } while (0) /* 3-component vector math */ #define VEC_NORM3(v) \ { \ GLfloat recM = fast_reciprocal_sqrt(v.x*v.x + v.y*v.y + v.z*v.z); \ v.x *= recM; \ v.y *= recM; \ v.z *= recM; \ } #define VEC_LEN3(v) fast_sqrt(v.x*v.x + v.y*v.y + v.z*v.z) #define VEC_REC_LEN3(v) fast_reciprocal_sqrt(v.x*v.x + v.y*v.y + v.z*v.z) #define VEC_SUB3(v, a, b) \ { \ v.x = a.x - b.x; \ v.y = a.y - b.y; \ v.z = a.z - b.z; \ } #define VEC_ADD3(v, a, b) \ { \ v.x = a.x + b.x; \ v.y = a.y + b.y; \ v.z = a.z + b.z; \ } #define VEC_SCALE3(v, _s) \ { \ GLfloat s = _s; \ v.x *= s; \ v.y *= s; \ v.z *= s; \ } /* 4-component vector math */ #define VEC_NORM4(v) \ { \ GLfloat recM; \ v.x /= v.w; \ v.y /= v.w; \ v.z /= v.w; \ v.w = 1.0; \ recM = fast_reciprocal_sqrt(v.x*v.x + v.y*v.y + v.z*v.z); \ v.x *= recM; \ v.y *= recM; \ v.z *= recM; \ } #define VEC_SUB4(v, a, b) \ { \ v.x = a.x - b.x; \ v.y = a.y - b.y; \ v.z = a.z - b.z; \ v.w = a.w - b.w; \ } #define VEC_ADD4(v, a, b) \ { \ v.x = a.x + b.x; \ v.y = a.y + b.y; \ v.z = a.z + b.z; \ v.w = a.w + b.w; \ } #define VEC4_VEC3(v) \ { \ v.x /= v.w; \ v.y /= v.w; \ v.z /= v.w; \ v.w = 1.0; \ } void light_UpdateAmbient(GLcontext context, GLmaterial *mat) { int i; if(!context->enable.Lighting) { return; } for (i = 0; i <= context->lighting.MaxLight; i++) { if (context->enable.Light[i]) { COLOR_MULT(context->lighting.Light[i].Acm_by_Acli[mat->Index], mat->Ambient, context->lighting.Light[i].Ambient); } } } void light_UpdateDiffuse(GLcontext context, GLmaterial *mat) { int i; if(!context->enable.Lighting) { return; } for (i = 0; i <= context->lighting.MaxLight; i++) { if (context->enable.Light[i]) { COLOR_MULT(context->lighting.Light[i].Dcm_by_Dcli[mat->Index], mat->Diffuse, context->lighting.Light[i].Diffuse); } } } void light_UpdateSpecular(GLcontext context, GLmaterial *mat) { int i; if(!context->enable.Lighting) { return; } for (i = 0; i <= context->lighting.MaxLight; i++) { if (context->enable.Light[i]) { COLOR_MULT(context->lighting.Light[i].Scm_by_Scli[mat->Index], mat->Specular, context->lighting.Light[i].Specular); } } } void light_Recalculate(GLcontext context, GLuint light) { /* Unconditionally re-build precalcs... Used when enabling a light */ COLOR_MULT(context->lighting.Light[light].Acm_by_Acli[FRONT_MAT_INDEX], context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.Light[light].Ambient); COLOR_MULT(context->lighting.Light[light].Acm_by_Acli[BACK_MAT_INDEX], context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.Light[light].Ambient); COLOR_MULT(context->lighting.Light[light].Dcm_by_Dcli[FRONT_MAT_INDEX], context->lighting.Material[FRONT_MAT_INDEX].Diffuse, context->lighting.Light[light].Diffuse); COLOR_MULT(context->lighting.Light[light].Dcm_by_Dcli[BACK_MAT_INDEX], context->lighting.Material[BACK_MAT_INDEX].Diffuse, context->lighting.Light[light].Diffuse); COLOR_MULT(context->lighting.Light[light].Scm_by_Scli[FRONT_MAT_INDEX], context->lighting.Material[FRONT_MAT_INDEX].Specular, context->lighting.Light[light].Specular); COLOR_MULT(context->lighting.Light[light].Scm_by_Scli[BACK_MAT_INDEX], context->lighting.Material[BACK_MAT_INDEX].Specular, context->lighting.Light[light].Specular); context->lighting.Light[light].OneOverConstantAttenuation = 1.0 / context->lighting.Light[light].ConstantAttenuation; } void light_CalcDirectionVector(MGLDirection *res, MGLPosition *p1, MGLPosition *p2) { if (p2->w == 0.0 && p1->w != 0.0) { res->x = p2->x; res->y = p2->y; res->z = p2->z; } else if (p1->w == 0.0 && p2->w != 0.0) { res->x = -p1->x; res->y = -p1->y; res->z = -p1->z; } else if (p1->w == 0.0 && p2->w == 0.0) { res->x = p2->x - p1->x; res->y = p2->y - p1->y; res->z = p2->z - p1->z; } else { #if 0 res->x = (p2->x/p2->w) - (p1->x/p1->w); res->y = (p2->y/p2->w) - (p1->y/p1->w); res->z = (p2->z/p2->w) - (p1->z/p1->w); #else res->x = (p2->x * p1->w) - (p1->x * p2->w); res->y = (p2->y * p1->w) - (p1->y * p2->w); res->z = (p2->z * p1->w) - (p1->z * p2->w); #endif } } void light_LightVertex(GLcontext context, GLuint vertex, GLfloat area) { MGLColor Cpri; GLmaterial *mat; int i; MGLDirection Normal; area = -area; /* Select the material, depending on two-sided more, and area */ if (context->lighting.LightModelTwoSide) { if (context->polygon.FrontFace == GL_CCW) { if (area <= 0) { mat = &context->lighting.Material[BACK_MAT_INDEX]; } else { mat = &context->lighting.Material[FRONT_MAT_INDEX]; } } else { if (-area <= 0) { mat = &context->lighting.Material[BACK_MAT_INDEX]; } else { mat = &context->lighting.Material[FRONT_MAT_INDEX]; } } } else { mat = &context->lighting.Material[FRONT_MAT_INDEX]; } Normal.x = context->VertexBuffer[vertex].EyeNormal.x; Normal.y = context->VertexBuffer[vertex].EyeNormal.y; Normal.z = context->VertexBuffer[vertex].EyeNormal.z; /* Compute Ecm + Acm*Acs */ COLOR_ADD(Cpri, mat->Emission, mat->Acm_Acs); /* Compute the per-light terms */ for (i = 0; i <= context->lighting.MaxLight; i++) { if (context->enable.Light[i]) { GLfloat atti = 1.0; GLfloat spoti = 1.0; GLfloat n_dot_VPpli; GLfloat VPpli_len; GLfloat n_dot_h_hat_i; MGLDirection VPpli; MGLDirection h_hat_i; GLlight *light = &context->lighting.Light[i]; MGLColor Clocal = {0.0, 0.0, 0.0}; light_CalcDirectionVector(&VPpli, &context->VertexBuffer[vertex].eye, &light->Position); VPpli_len = VEC_LEN3(VPpli); VEC_SCALE3(VPpli, 1.0/VPpli_len); /* Attenuation */ if (light->Position.w != 0.0) { if (light->LinearAttenuation == 0.0 && light->QuadraticAttenuation == 0.0) atti = light->OneOverConstantAttenuation; else { atti = light->ConstantAttenuation + (light->LinearAttenuation + light->QuadraticAttenuation * VPpli_len) * VPpli_len; if (atti != 0.0) atti = 1.0 / atti; } } /* Spotlight effect */ if (light->SpotCutoff != 180.0f) { MGLDirection *nSpotDir = &light->NormSpotDirection; GLfloat spot_dot_VPpli = -(nSpotDir->x * VPpli.x + nSpotDir->y * VPpli.y + nSpotDir->z * VPpli.z); if(context->lighting.LightModelTwoSide && spot_dot_VPpli < 0) { spot_dot_VPpli = -spot_dot_VPpli; } if(spot_dot_VPpli >= light->CosineSpotCutoff) { spoti = pow(spot_dot_VPpli, light->SpotExponent); } else { spoti = 0.0; } } /* The rest of the lighting depends on atti and spoti: if one is 0, the * light source contributes nothing, so we ignore it */ if (atti != 0.0 && spoti != 0.0) { /* Term 1: Acm * Acli */ COLOR_ADD(Clocal, Clocal, light->Acm_by_Acli[mat->Index]); /* Term 2: (n o VPPli) Dcm * Dcli */ n_dot_VPpli = max_dot(&Normal, &VPpli); if (n_dot_VPpli != 0.0) { COLOR_ADD_SCALED(Clocal, n_dot_VPpli, light->Dcm_by_Dcli[mat->Index]); /* Term 3 starts here * Term 3: (fi)(n o h_hat_i)^Srm * Scm * Scli * Start with h_hat_i */ if (context->lighting.LightModelLocalViewer) { MGLDirection VPe; VPe.x = -context->VertexBuffer[vertex].eye.x; VPe.y = -context->VertexBuffer[vertex].eye.y; VPe.z = -context->VertexBuffer[vertex].eye.z; VEC_NORM3(VPe); VEC_ADD3(h_hat_i, VPpli, VPe); } else { h_hat_i.x = VPpli.x; h_hat_i.y = VPpli.y; h_hat_i.z = VPpli.z + 1.0; } VEC_NORM3(h_hat_i); n_dot_h_hat_i = max_dot(&Normal, &h_hat_i); if (n_dot_h_hat_i != 0) COLOR_ADD_SCALED(Clocal, pow(n_dot_h_hat_i, mat->Shininess), light->Scm_by_Scli[mat->Index]); } /* if (n_dot_VPpli */ } /* if (atti != 0.0 ... */ /* Finally, add the local contribution to the rest of the bunch */ COLOR_ADD_SCALED(Cpri, atti*spoti, Clocal); } /* if (context->light ... */ } /* for (i = 0; i <= context->MaxLight ... */ /* Set the vertex color accordingly */ context->VertexBuffer[vertex].r = CLAMPF(Cpri.r); context->VertexBuffer[vertex].g = CLAMPF(Cpri.g); context->VertexBuffer[vertex].b = CLAMPF(Cpri.b); context->VertexBuffer[vertex].a = CLAMPF(mat->Diffuse.a); } void cgl_GLMaterialf(struct GLContextIFace *Self, GLenum face, GLenum pname, GLfloat param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Materialf(Self, face, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } switch (pname) { case GL_SHININESS: switch (face) { case GL_FRONT: context->lighting.Material[FRONT_MAT_INDEX].Shininess = param; break; case GL_BACK: context->lighting.Material[BACK_MAT_INDEX].Shininess = param; break; case GL_FRONT_AND_BACK: context->lighting.Material[FRONT_MAT_INDEX].Shininess = param; context->lighting.Material[BACK_MAT_INDEX].Shininess = param; break; default: context->CurrentError = GL_INVALID_ENUM; return; } break; default: context->CurrentError = GL_INVALID_ENUM; return; } } void cgl_GLMaterialfv(struct GLContextIFace *Self, GLenum face, GLenum pname, const GLfloat* param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Materialfv(Self, face, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLmaterial *m1 = 0, *m2 = 0; switch (face) { case GL_FRONT: m1 = &context->lighting.Material[FRONT_MAT_INDEX]; break; case GL_BACK: m1 = &context->lighting.Material[BACK_MAT_INDEX]; break; case GL_FRONT_AND_BACK: m1 = &context->lighting.Material[FRONT_MAT_INDEX]; m2 = &context->lighting.Material[BACK_MAT_INDEX]; break; default: context->CurrentError = GL_INVALID_ENUM; return; } switch (pname) { default: context->CurrentError = GL_INVALID_ENUM; return; case GL_AMBIENT: m1->Ambient.r = param[0]; m1->Ambient.g = param[1]; m1->Ambient.b = param[2]; m1->Ambient.a = param[3]; COLOR_MULT(m1->Acm_Acs, m1->Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, m1); if (m2) { m2->Ambient.r = param[0]; m2->Ambient.g = param[1]; m2->Ambient.b = param[2]; m2->Ambient.a = param[3]; COLOR_MULT(m2->Acm_Acs, m2->Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, m2); } break; case GL_DIFFUSE: m1->Diffuse.r = param[0]; m1->Diffuse.g = param[1]; m1->Diffuse.b = param[2]; m1->Diffuse.a = param[3]; light_UpdateDiffuse(context, m1); if (m2) { m2->Diffuse.r = param[0]; m2->Diffuse.g = param[1]; m2->Diffuse.b = param[2]; m2->Diffuse.a = param[3]; light_UpdateDiffuse(context, m2); } break; case GL_AMBIENT_AND_DIFFUSE: m1->Ambient.r = param[0]; m1->Ambient.g = param[1]; m1->Ambient.b = param[2]; m1->Ambient.a = param[3]; m1->Diffuse.r = param[0]; m1->Diffuse.g = param[1]; m1->Diffuse.b = param[2]; m1->Diffuse.a = param[3]; COLOR_MULT(m1->Acm_Acs, m1->Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, m1); light_UpdateDiffuse(context, m1); if (m2) { m2->Ambient.r = param[0]; m2->Ambient.g = param[1]; m2->Ambient.b = param[2]; m2->Ambient.a = param[3]; m2->Diffuse.r = param[0]; m2->Diffuse.g = param[1]; m2->Diffuse.b = param[2]; m2->Diffuse.a = param[3]; COLOR_MULT(m2->Acm_Acs, m2->Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, m2); light_UpdateDiffuse(context, m2); } break; case GL_SPECULAR: m1->Specular.r = param[0]; m1->Specular.g = param[1]; m1->Specular.b = param[2]; m1->Specular.a = param[3]; light_UpdateSpecular(context, m1); if (m2) { m2->Specular.r = param[0]; m2->Specular.g = param[1]; m2->Specular.b = param[2]; m2->Specular.a = param[3]; light_UpdateSpecular(context, m2); } break; case GL_EMISSION: m1->Emission.r = param[0]; m1->Emission.g = param[1]; m1->Emission.b = param[2]; m1->Emission.a = param[3]; if (m2) { m2->Emission.r = param[0]; m2->Emission.g = param[1]; m2->Emission.b = param[2]; m2->Emission.a = param[3]; } break; case GL_SHININESS: m1->Shininess = param[0]; if (m2) m2->Shininess = param[0]; break; } } void cgl_GLMaterialiv(struct GLContextIFace *Self, GLenum face, GLenum pname, const GLint* param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Materialiv(Self, face, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLfloat f[4]; GLfloat one_over_255 = 1.0/255.0; switch (pname) { default: context->CurrentError = GL_INVALID_ENUM; return; case GL_AMBIENT: case GL_DIFFUSE: case GL_AMBIENT_AND_DIFFUSE: case GL_SPECULAR: case GL_EMISSION: f[0] = (GLfloat)param[0] * one_over_255; f[1] = (GLfloat)param[1] * one_over_255; f[2] = (GLfloat)param[2] * one_over_255; f[3] = (GLfloat)param[3] * one_over_255; Self->GLMaterialfv(face, pname, f); break; case GL_SHININESS: Self->GLMaterialf(face, pname, (GLfloat)param[0]); break; } } void cgl_GLLightf(struct GLContextIFace *Self, GLenum light, GLenum pname, GLfloat param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Lightf(Self, light, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLlight *li; GLFlagError(context, light < GL_LIGHT0 || light > (GL_LIGHT0+MGL_MAX_LIGHTS), GL_INVALID_ENUM); li = &context->lighting.Light[light - GL_LIGHT0]; switch (pname) { default: context->CurrentError = GL_INVALID_ENUM; break; case GL_SPOT_EXPONENT: GLFlagError(context, param > 128.0, GL_INVALID_VALUE); li->SpotExponent = param; break; case GL_SPOT_CUTOFF: { if(param == 180.0) { li->SpotCutoff = param; } else { GLFlagError(context, param > 90.0, GL_INVALID_VALUE); li->SpotCutoff = param; } li->CosineSpotCutoff = cos(li->SpotCutoff * M_PI / 180.0); break; } case GL_CONSTANT_ATTENUATION: li->ConstantAttenuation = param; li->OneOverConstantAttenuation = 1.0/param; break; case GL_LINEAR_ATTENUATION: li->LinearAttenuation = param; break; case GL_QUADRATIC_ATTENUATION: li->QuadraticAttenuation = param; break; } } void cgl_GLLightfv(struct GLContextIFace *Self, GLenum light_num, GLenum pname, const GLfloat* param) { #define a(x) (CurrentMV->v[OF_##x]) GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Lightfv(Self, light_num, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLlight *light; GLFlagError(context, light_num < GL_LIGHT0 || light_num > (GL_LIGHT0+MGL_MAX_LIGHTS), GL_INVALID_ENUM); light = &context->lighting.Light[light_num - GL_LIGHT0]; switch (pname) { default: context->CurrentError = GL_INVALID_ENUM; break; case GL_AMBIENT: light->Ambient.r = param[0]; light->Ambient.g = param[1]; light->Ambient.b = param[2]; light->Ambient.a = param[3]; COLOR_MULT(light->Acm_by_Acli[FRONT_MAT_INDEX], light->Ambient, context->lighting.Material[FRONT_MAT_INDEX].Ambient); COLOR_MULT(light->Acm_by_Acli[BACK_MAT_INDEX], light->Ambient, context->lighting.Material[BACK_MAT_INDEX].Ambient); break; case GL_DIFFUSE: light->Diffuse.r = param[0]; light->Diffuse.g = param[1]; light->Diffuse.b = param[2]; light->Diffuse.a = param[3]; COLOR_MULT(light->Dcm_by_Dcli[FRONT_MAT_INDEX], light->Diffuse, context->lighting.Material[FRONT_MAT_INDEX].Diffuse); COLOR_MULT(light->Dcm_by_Dcli[BACK_MAT_INDEX], light->Diffuse, context->lighting.Material[FRONT_MAT_INDEX].Diffuse); break; case GL_SPECULAR: light->Specular.r = param[0]; light->Specular.g = param[1]; light->Specular.b = param[2]; light->Specular.a = param[3]; COLOR_MULT(light->Scm_by_Scli[FRONT_MAT_INDEX], light->Specular, context->lighting.Material[FRONT_MAT_INDEX].Specular); COLOR_MULT(light->Scm_by_Scli[BACK_MAT_INDEX], light->Specular, context->lighting.Material[FRONT_MAT_INDEX].Specular); break; case GL_POSITION: /* Position is transformed by current modelview matrix */ light->Position.x = a(11)*param[0] + a(12)*param[1] + a(13)*param[2] + a(14)*param[3]; light->Position.y = a(21)*param[0] + a(22)*param[1] + a(23)*param[2] + a(24)*param[3]; light->Position.z = a(31)*param[0] + a(32)*param[1] + a(33)*param[2] + a(34)*param[3]; light->Position.w = a(41)*param[0] + a(42)*param[1] + a(43)*param[2] + a(44)*param[3]; break; case GL_SPOT_DIRECTION: /* Direction is only transformed by the upper 3x3 part of modelview */ light->SpotDirection.x = a(11)*param[0] + a(12)*param[1] + a(13)*param[2]; light->SpotDirection.y = a(21)*param[0] + a(22)*param[1] + a(23)*param[2]; light->SpotDirection.z = a(31)*param[0] + a(32)*param[1] + a(33)*param[2]; light->NormSpotDirection.x = light->SpotDirection.x; light->NormSpotDirection.y = light->SpotDirection.y; light->NormSpotDirection.z = light->SpotDirection.z; VEC_NORM3(light->NormSpotDirection); break; case GL_SPOT_EXPONENT: GLFlagError(context, param[0] > 128.0, GL_INVALID_VALUE); light->SpotExponent = param[0]; break; case GL_SPOT_CUTOFF: GLFlagError(context, param[0] > 90.0, GL_INVALID_VALUE); light->SpotCutoff = param[0]; break; case GL_CONSTANT_ATTENUATION: light->ConstantAttenuation = param[0]; light->OneOverConstantAttenuation = 1.0 / light->ConstantAttenuation; break; case GL_LINEAR_ATTENUATION: light->LinearAttenuation = param[0]; break; case GL_QUADRATIC_ATTENUATION: light->QuadraticAttenuation = param[0]; break; } #undef a } void cgl_GLLightiv(struct GLContextIFace *Self, GLenum light_num, GLenum pname, const GLint* param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Lightiv(Self, light_num, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLlight *light; GLfloat f[4]; GLfloat one_over_255 = 1.0 / 255.0; GLFlagError(context, light_num < GL_LIGHT0 || light_num > (GL_LIGHT0+MGL_MAX_LIGHTS), GL_INVALID_ENUM); light = &context->lighting.Light[light_num - GL_LIGHT0]; switch (pname) { default: context->CurrentError = GL_INVALID_ENUM; break; case GL_AMBIENT: light->Ambient.r = (GLfloat)param[0] * one_over_255; light->Ambient.g = (GLfloat)param[1] * one_over_255; light->Ambient.b = (GLfloat)param[2] * one_over_255; light->Ambient.a = (GLfloat)param[3] * one_over_255; COLOR_MULT(light->Acm_by_Acli[FRONT_MAT_INDEX], light->Ambient, context->lighting.Material[FRONT_MAT_INDEX].Ambient); COLOR_MULT(light->Acm_by_Acli[BACK_MAT_INDEX], light->Ambient, context->lighting.Material[BACK_MAT_INDEX].Ambient); break; case GL_DIFFUSE: light->Diffuse.r = (GLfloat)param[0] * one_over_255; light->Diffuse.g = (GLfloat)param[1] * one_over_255; light->Diffuse.b = (GLfloat)param[2] * one_over_255; light->Diffuse.a = (GLfloat)param[3] * one_over_255; COLOR_MULT(light->Dcm_by_Dcli[FRONT_MAT_INDEX], light->Diffuse, context->lighting.Material[FRONT_MAT_INDEX].Diffuse); COLOR_MULT(light->Dcm_by_Dcli[BACK_MAT_INDEX], light->Diffuse, context->lighting.Material[FRONT_MAT_INDEX].Diffuse); break; case GL_SPECULAR: light->Specular.r = (GLfloat)param[0] * one_over_255; light->Specular.g = (GLfloat)param[1] * one_over_255; light->Specular.b = (GLfloat)param[2] * one_over_255; light->Specular.a = (GLfloat)param[3] * one_over_255; COLOR_MULT(light->Scm_by_Scli[FRONT_MAT_INDEX], light->Specular, context->lighting.Material[FRONT_MAT_INDEX].Specular); COLOR_MULT(light->Scm_by_Scli[BACK_MAT_INDEX], light->Specular, context->lighting.Material[FRONT_MAT_INDEX].Specular); break; case GL_POSITION: f[0] = (GLfloat)param[0]; f[1] = (GLfloat)param[1]; f[2] = (GLfloat)param[2]; f[3] = (GLfloat)param[3]; Self->GLLightfv(light_num, pname, f); break; case GL_SPOT_DIRECTION: f[0] = (GLfloat)param[0]; f[1] = (GLfloat)param[1]; f[2] = (GLfloat)param[2]; Self->GLLightfv(light_num, pname, f); break; case GL_SPOT_EXPONENT: GLFlagError(context, param[0] > 128, GL_INVALID_VALUE); light->SpotExponent = (GLfloat)param[0]; break; case GL_SPOT_CUTOFF: GLFlagError(context, param[0] > 90, GL_INVALID_VALUE); light->SpotCutoff = (GLfloat)param[0]; break; case GL_CONSTANT_ATTENUATION: light->ConstantAttenuation = (GLfloat)param[0]; light->OneOverConstantAttenuation = 1.0 / light->ConstantAttenuation; break; case GL_LINEAR_ATTENUATION: light->LinearAttenuation = (GLfloat)param[0]; break; case GL_QUADRATIC_ATTENUATION: light->QuadraticAttenuation = (GLfloat)param[0]; break; } } void cgl_GLLightModelf(struct GLContextIFace *Self, GLenum pname, GLfloat param) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LightModelf(Self, pname, param); if(!dl_CompileAndExecuteMode(Self)){ return; } } switch (pname) { case GL_LIGHT_MODEL_LOCAL_VIEWER: context->lighting.LightModelLocalViewer = (param != 0); break; case GL_LIGHT_MODEL_TWO_SIDE: context->lighting.LightModelTwoSide = (param != 0); break; case GL_LIGHT_MODEL_COLOR_CONTROL: context->lighting.LightModelColorControl = param; break; default: context->CurrentError = GL_INVALID_ENUM; } } void cgl_GLLightModelfv(struct GLContextIFace *Self, GLenum pname, const GLfloat* params) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LightModelfv(Self, pname, params); if(!dl_CompileAndExecuteMode(Self)){ return; } } switch (pname) { case GL_LIGHT_MODEL_AMBIENT: context->lighting.LightModelAmbient.r = params[0]; context->lighting.LightModelAmbient.g = params[1]; context->lighting.LightModelAmbient.b = params[2]; context->lighting.LightModelAmbient.a = params[3]; COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: context->lighting.LightModelLocalViewer = (params[0] != 0.0); break; case GL_LIGHT_MODEL_TWO_SIDE: context->lighting.LightModelTwoSide = (params[0] != 0.0); break; case GL_LIGHT_MODEL_COLOR_CONTROL: context->lighting.LightModelColorControl = params[0]; break; default: context->CurrentError = GL_INVALID_ENUM; return; } } void cgl_GLLightModeliv(struct GLContextIFace *Self, GLenum pname, const GLint* params) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LightModeliv(Self, pname, params); if(!dl_CompileAndExecuteMode(Self)){ return; } } GLfloat one_over_255 = 1.0 / 255.0; switch (pname) { case GL_LIGHT_MODEL_AMBIENT: context->lighting.LightModelAmbient.r = (GLfloat)params[0] * one_over_255; context->lighting.LightModelAmbient.g = (GLfloat)params[1] * one_over_255; context->lighting.LightModelAmbient.b = (GLfloat)params[2] * one_over_255; context->lighting.LightModelAmbient.a = (GLfloat)params[3] * one_over_255; COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: context->lighting.LightModelLocalViewer = (params[0] != 0); break; case GL_LIGHT_MODEL_TWO_SIDE: context->lighting.LightModelTwoSide = (params[0] != 0); break; case GL_LIGHT_MODEL_COLOR_CONTROL: context->lighting.LightModelColorControl = params[0]; break; default: context->CurrentError = GL_INVALID_ENUM; return; } } void cgl_GLColorMaterial(struct GLContextIFace *Self, GLenum face, GLenum mode) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_ColorMaterial(Self, face, mode); if(!dl_CompileAndExecuteMode(Self)){ return; } } switch (mode) { case GL_EMISSION: case GL_AMBIENT: case GL_DIFFUSE: case GL_SPECULAR: case GL_AMBIENT_AND_DIFFUSE: break; default: context->CurrentError = GL_INVALID_ENUM; return; } context->lighting.ColorMaterialParameter = mode; context->lighting.ColorMaterialFace = face; switch (face) { case GL_FRONT: switch (mode) { case GL_EMISSION: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Emission; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = 0; break; case GL_AMBIENT: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Ambient; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_AMBIENT; break; case GL_DIFFUSE: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Diffuse; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_DIFFUSE; break; case GL_SPECULAR: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Specular; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_SPECULAR; break; case GL_AMBIENT_AND_DIFFUSE: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Ambient; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[FRONT_MAT_INDEX].Diffuse; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; break; default: context->CurrentError = GL_INVALID_ENUM; return; } break; case GL_BACK: switch (mode) { case GL_EMISSION: context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Emission; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = 0; break; case GL_AMBIENT: context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Ambient; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_AMBIENT; break; case GL_DIFFUSE: context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Diffuse; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_DIFFUSE; break; case GL_SPECULAR: context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Specular; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_SPECULAR; break; case GL_AMBIENT_AND_DIFFUSE: context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Ambient; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[BACK_MAT_INDEX].Diffuse; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; break; default: context->CurrentError = GL_INVALID_ENUM; return; } break; case GL_FRONT_AND_BACK: switch (mode) { case GL_EMISSION: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Emission; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = 0; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Emission; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = 0; break; case GL_AMBIENT: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Ambient; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_AMBIENT; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Ambient; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_AMBIENT; break; case GL_DIFFUSE: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Diffuse; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_DIFFUSE; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Diffuse; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_DIFFUSE; break; case GL_SPECULAR: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Specular; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_SPECULAR; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Specular; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = 0; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_SPECULAR; break; case GL_AMBIENT_AND_DIFFUSE: context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Ambient; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[FRONT_MAT_INDEX].Diffuse; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Ambient; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[BACK_MAT_INDEX].Diffuse; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; break; default: context->CurrentError = GL_INVALID_ENUM; return; } break; } } void light_UpdateColorMaterial(GLcontext context) { if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->r = context->current.CurrentColor.r; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->g = context->current.CurrentColor.g; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->b = context->current.CurrentColor.b; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->a = context->current.CurrentColor.a; } if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->r = context->current.CurrentColor.r; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->g = context->current.CurrentColor.g; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->b = context->current.CurrentColor.b; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->a = context->current.CurrentColor.a; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->r = context->current.CurrentColor.r; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->g = context->current.CurrentColor.g; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->b = context->current.CurrentColor.b; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->a = context->current.CurrentColor.a; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->r = context->current.CurrentColor.r; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->g = context->current.CurrentColor.g; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->b = context->current.CurrentColor.b; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->a = context->current.CurrentColor.a; } if (context->lighting.Material[FRONT_MAT_INDEX].Update) { if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[FRONT_MAT_INDEX]); if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update) { if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[BACK_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[BACK_MAT_INDEX]); if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[BACK_MAT_INDEX]); } } void light_UpdateColorMaterialColor(GLcontext context, const GLfloat color[4]) { if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->r = color[0]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->g = color[1]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->b = color[2]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->a = color[3]; } if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->r = color[0]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->g = color[1]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->b = color[2]; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->a = color[3]; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->r = color[0]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->g = color[1]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->b = color[2]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->a = color[3]; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->r = color[0]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->g = color[1]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->b = color[2]; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->a = color[3]; } if (context->lighting.Material[FRONT_MAT_INDEX].Update) { if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[FRONT_MAT_INDEX]); if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update) { if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[BACK_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[BACK_MAT_INDEX]); if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[BACK_MAT_INDEX]); } } void light_UpdateColorMaterialVertex(GLcontext context) { MGLVertex *current = &context->VertexBuffer[context->VertexBufferPointer]; if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->r = current->r; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->g = current->g; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->b = current->b; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0]->a = current->a; } if (context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->r = current->r; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->g = current->g; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->b = current->b; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1]->a = current->a; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->r = current->r; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->g = current->g; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->b = current->b; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0]->a = current->a; } if (context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]) { context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->r = current->r; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->g = current->g; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->b = current->b; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1]->a = current->a; } if (context->lighting.Material[FRONT_MAT_INDEX].Update) { if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[FRONT_MAT_INDEX]); if (context->lighting.Material[FRONT_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[FRONT_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update) { if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_AMBIENT) { COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); light_UpdateAmbient(context, &context->lighting.Material[BACK_MAT_INDEX]); } if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_DIFFUSE) light_UpdateDiffuse(context, &context->lighting.Material[BACK_MAT_INDEX]); if (context->lighting.Material[BACK_MAT_INDEX].Update & MAT_UPDATE_SPECULAR) light_UpdateSpecular(context, &context->lighting.Material[BACK_MAT_INDEX]); } } void cgl_GLGetLightfv(struct GLContextIFace *Self, GLenum light_num, GLenum pname, GLfloat *param) { GLcontext context = GET_INSTANCE(Self); dprintf("called\n"); GLlight *light; GLFlagError(context, light_num < GL_LIGHT0 || light_num > (GL_LIGHT0+MGL_MAX_LIGHTS), GL_INVALID_ENUM); light = &context->lighting.Light[light_num - GL_LIGHT0]; switch (pname) { case GL_AMBIENT: param[0] = light->Ambient.r; param[1] = light->Ambient.g; param[2] = light->Ambient.b; param[3] = light->Ambient.a; break; case GL_DIFFUSE: param[0] = light->Diffuse.r; param[1] = light->Diffuse.g; param[2] = light->Diffuse.b; param[3] = light->Diffuse.a; break; case GL_SPECULAR: param[0] = light->Specular.r; param[1] = light->Specular.g; param[2] = light->Specular.b; param[3] = light->Specular.a; break; case GL_POSITION: /* To be considered: is this correct ? The specs say that these are * returned in eye coordinates, which means they are transformed * by the current modelview already. */ param[0] = light->Position.x; param[1] = light->Position.y; param[2] = light->Position.z; param[3] = light->Position.w; break; case GL_SPOT_DIRECTION: /* To be considered: is this correct ? The specs say that these are * returned in eye coordinates, which means they are transformed * by the current modelview already. */ param[0] = light->SpotDirection.x; param[1] = light->SpotDirection.y; param[2] = light->SpotDirection.z; break; case GL_SPOT_EXPONENT: param[0] = light->SpotExponent; break; case GL_SPOT_CUTOFF: param[0] = light->SpotCutoff ; break; case GL_CONSTANT_ATTENUATION: param[0] = light->ConstantAttenuation; break; case GL_LINEAR_ATTENUATION: param[0] = light->LinearAttenuation; break; case GL_QUADRATIC_ATTENUATION: param[0] = light->QuadraticAttenuation; break; default: context->CurrentError = GL_INVALID_ENUM; break; } } void cgl_GLGetLightiv(struct GLContextIFace *Self, GLenum light_num, GLenum pname, GLint *param) { GLcontext context = GET_INSTANCE(Self); dprintf("called\n"); GLlight *light; GLFlagError(context, light_num < GL_LIGHT0 || light_num > (GL_LIGHT0+MGL_MAX_LIGHTS), GL_INVALID_ENUM); light = &context->lighting.Light[light_num - GL_LIGHT0]; switch (pname) { case GL_AMBIENT: param[0] = (GLint)light->Ambient.r; param[1] = (GLint)light->Ambient.g; param[2] = (GLint)light->Ambient.b; param[3] = (GLint)light->Ambient.a; break; case GL_DIFFUSE: param[0] = (GLint)light->Diffuse.r; param[1] = (GLint)light->Diffuse.g; param[2] = (GLint)light->Diffuse.b; param[3] = (GLint)light->Diffuse.a; break; case GL_SPECULAR: param[0] = (GLint)light->Specular.r; param[1] = (GLint)light->Specular.g; param[2] = (GLint)light->Specular.b; param[3] = (GLint)light->Specular.a; break; case GL_POSITION: /* To be considered: is this correct ? The specs say that these are * returned in eye coordinates, which means they are transformed * by the current modelview already. */ param[0] = (GLint)light->Position.x; param[1] = (GLint)light->Position.y; param[2] = (GLint)light->Position.z; param[3] = (GLint)light->Position.w; break; case GL_SPOT_DIRECTION: /* To be considered: is this correct ? The specs say that these are * returned in eye coordinates, which means they are transformed * by the current modelview already. */ param[0] = (GLint)light->SpotDirection.x; param[1] = (GLint)light->SpotDirection.y; param[2] = (GLint)light->SpotDirection.z; break; case GL_SPOT_EXPONENT: param[0] = (GLint)light->SpotExponent; break; case GL_SPOT_CUTOFF: param[0] = (GLint)light->SpotCutoff ; break; case GL_CONSTANT_ATTENUATION: param[0] = (GLint)light->ConstantAttenuation; break; case GL_LINEAR_ATTENUATION: param[0] = (GLint)light->LinearAttenuation; break; case GL_QUADRATIC_ATTENUATION: param[0] = (GLint)light->QuadraticAttenuation; break; default: context->CurrentError = GL_INVALID_ENUM; break; } } #endif void light_Init(GLcontext context) { #ifdef MGL_USE_LIGHTING int i; kprintf("Initializing lighting\n"); context->enable.Lighting = GL_FALSE; context->enable.ColorMaterial = GL_FALSE; MGL_SET_COLOR(context->lighting.LightModelAmbient, 0.2, 0.2, 0.2, 1.0); context->lighting.LightModelLocalViewer = GL_FALSE; context->lighting.LightModelTwoSide = GL_FALSE; context->lighting.LightModelColorControl = GL_SINGLE_COLOR; context->lighting.Material[FRONT_MAT_INDEX].Index = FRONT_MAT_INDEX; MGL_SET_COLOR(context->lighting.Material[FRONT_MAT_INDEX].Ambient, 0.2, 0.2, 0.2, 1.0); MGL_SET_COLOR(context->lighting.Material[FRONT_MAT_INDEX].Diffuse, 0.8, 0.8, 0.8, 1.0); MGL_SET_COLOR(context->lighting.Material[FRONT_MAT_INDEX].Specular, 0.0, 0.0, 0.0, 1.0); MGL_SET_COLOR(context->lighting.Material[FRONT_MAT_INDEX].Emission, 0.0, 0.0, 0.0, 1.0); context->lighting.Material[FRONT_MAT_INDEX].Shininess = 0.0; context->lighting.Material[BACK_MAT_INDEX].Index = BACK_MAT_INDEX; MGL_SET_COLOR(context->lighting.Material[BACK_MAT_INDEX].Ambient, 0.2, 0.2, 0.2, 1.0); MGL_SET_COLOR(context->lighting.Material[BACK_MAT_INDEX].Diffuse, 0.8, 0.8, 0.8, 1.0); MGL_SET_COLOR(context->lighting.Material[BACK_MAT_INDEX].Specular, 0.0, 0.0, 0.0, 1.0); MGL_SET_COLOR(context->lighting.Material[BACK_MAT_INDEX].Emission, 0.0, 0.0, 0.0, 1.0); context->lighting.Material[BACK_MAT_INDEX].Shininess = 0.0; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[FRONT_MAT_INDEX].Ambient; context->lighting.Material[FRONT_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[FRONT_MAT_INDEX].Diffuse; context->lighting.Material[FRONT_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[0] = &context->lighting.Material[BACK_MAT_INDEX].Ambient; context->lighting.Material[BACK_MAT_INDEX].ColorMaterial[1] = &context->lighting.Material[BACK_MAT_INDEX].Diffuse; context->lighting.Material[BACK_MAT_INDEX].Update = MAT_UPDATE_AMBIENT|MAT_UPDATE_DIFFUSE; for (i = 0; i < MGL_MAX_LIGHTS; i++) { context->enable.Light[i] = GL_FALSE; MGL_SET_COLOR(context->lighting.Light[i].Ambient, 0.0, 0.0, 0.0, 1.0); if (i == 0) { MGL_SET_COLOR(context->lighting.Light[i].Diffuse, 1.0, 1.0, 1.0, 1.0); MGL_SET_COLOR(context->lighting.Light[i].Specular, 1.0, 1.0, 1.0, 1.0); } else { MGL_SET_COLOR(context->lighting.Light[i].Diffuse, 0.0, 0.0, 0.0, 1.0); MGL_SET_COLOR(context->lighting.Light[i].Specular, 0.0, 0.0, 0.0, 1.0); } context->lighting.Light[i].Position.x = 0.0; context->lighting.Light[i].Position.y = 0.0; context->lighting.Light[i].Position.z = 1.0; context->lighting.Light[i].Position.w = 0.0; context->lighting.Light[i].SpotDirection.x = 0.0; context->lighting.Light[i].SpotDirection.y = 0.0; context->lighting.Light[i].SpotDirection.z = -1.0; context->lighting.Light[i].NormSpotDirection.x = 0.0; context->lighting.Light[i].NormSpotDirection.y = 0.0; context->lighting.Light[i].NormSpotDirection.z = -1.0; context->lighting.Light[i].SpotExponent = 0.0; context->lighting.Light[i].SpotCutoff = 180.0f; context->lighting.Light[i].ConstantAttenuation = 1.0; context->lighting.Light[i].LinearAttenuation = 0.0; context->lighting.Light[i].QuadraticAttenuation = 0.0; context->lighting.Light[i].OneOverConstantAttenuation = 1.0; context->lighting.Light[i].CosineSpotCutoff = -1.0; } COLOR_MULT(context->lighting.Material[FRONT_MAT_INDEX].Acm_Acs, context->lighting.Material[FRONT_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); COLOR_MULT(context->lighting.Material[BACK_MAT_INDEX].Acm_Acs, context->lighting.Material[BACK_MAT_INDEX].Ambient, context->lighting.LightModelAmbient); context->lighting.MaxLight = -1; #endif } void cgl_GLGetMaterialfv(struct GLContextIFace *Self, GLenum face, GLenum value, GLfloat *data) { GLcontext context = GET_INSTANCE(Self); GLmaterial *m1; switch (face) { case GL_FRONT: m1 = &context->lighting.Material[FRONT_MAT_INDEX]; break; case GL_BACK: m1 = &context->lighting.Material[BACK_MAT_INDEX]; break; default: context->CurrentError = GL_INVALID_ENUM; return; } switch (value) { case GL_AMBIENT: *data ++ = m1->Ambient.r; *data ++ = m1->Ambient.g; *data ++ = m1->Ambient.b; *data ++ = m1->Ambient.a; break; case GL_DIFFUSE: *data ++ = m1->Diffuse.r; *data ++ = m1->Diffuse.g; *data ++ = m1->Diffuse.b; *data ++ = m1->Diffuse.a; break; case GL_SPECULAR: *data ++ = m1->Specular.r; *data ++ = m1->Specular.g; *data ++ = m1->Specular.b; *data ++ = m1->Specular.a; break; case GL_EMISSION: *data ++ = m1->Emission.r; *data ++ = m1->Emission.g; *data ++ = m1->Emission.b; *data ++ = m1->Emission.a; break; case GL_SHININESS: *data ++ = m1->Shininess; break; default: context->CurrentError = GL_INVALID_ENUM; return; } } void cgl_GLGetMaterialiv(struct GLContextIFace *Self, GLenum face, GLenum value, GLint *data) { GLcontext context = GET_INSTANCE(Self); GLmaterial *m1; switch (face) { case GL_FRONT: m1 = &context->lighting.Material[FRONT_MAT_INDEX]; break; case GL_BACK: m1 = &context->lighting.Material[BACK_MAT_INDEX]; break; default: context->CurrentError = GL_INVALID_ENUM; return; } switch (value) { case GL_AMBIENT: *data ++ = (GLint)m1->Ambient.r; *data ++ = (GLint)m1->Ambient.g; *data ++ = (GLint)m1->Ambient.b; *data ++ = (GLint)m1->Ambient.a; break; case GL_DIFFUSE: *data ++ = (GLint)m1->Diffuse.r; *data ++ = (GLint)m1->Diffuse.g; *data ++ = (GLint)m1->Diffuse.b; *data ++ = (GLint)m1->Diffuse.a; break; case GL_SPECULAR: *data ++ = (GLint)m1->Specular.r; *data ++ = (GLint)m1->Specular.g; *data ++ = (GLint)m1->Specular.b; *data ++ = (GLint)m1->Specular.a; break; case GL_EMISSION: *data ++ = (GLint)m1->Emission.r; *data ++ = (GLint)m1->Emission.g; *data ++ = (GLint)m1->Emission.b; *data ++ = (GLint)m1->Emission.a; break; case GL_SHININESS: *data ++ = (GLint)m1->Shininess; break; default: context->CurrentError = GL_INVALID_ENUM; return; } }