⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 light.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
         }	 if (ctx->Light.Model.ColorControl == newenum)	    return;	 FLUSH_VERTICES(ctx, _NEW_LIGHT);	 ctx->Light.Model.ColorControl = newenum;         break;      default:         _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );         break;   }   if (ctx->Driver.LightModelfv)      ctx->Driver.LightModelfv( ctx, pname, params );}void GLAPIENTRY_mesa_LightModeliv( GLenum pname, const GLint *params ){   GLfloat fparam[4];   switch (pname) {      case GL_LIGHT_MODEL_AMBIENT:         fparam[0] = INT_TO_FLOAT( params[0] );         fparam[1] = INT_TO_FLOAT( params[1] );         fparam[2] = INT_TO_FLOAT( params[2] );         fparam[3] = INT_TO_FLOAT( params[3] );         break;      case GL_LIGHT_MODEL_LOCAL_VIEWER:      case GL_LIGHT_MODEL_TWO_SIDE:      case GL_LIGHT_MODEL_COLOR_CONTROL:         fparam[0] = (GLfloat) params[0];         break;      default:         /* Error will be caught later in gl_LightModelfv */         ;   }   _mesa_LightModelfv( pname, fparam );}void GLAPIENTRY_mesa_LightModeli( GLenum pname, GLint param ){   _mesa_LightModeliv( pname, &param );}void GLAPIENTRY_mesa_LightModelf( GLenum pname, GLfloat param ){   _mesa_LightModelfv( pname, &param );}/********** MATERIAL **********//* * Given a face and pname value (ala glColorMaterial), compute a bitmask * of the targeted material values. */GLuint_mesa_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,                        GLuint legal, const char *where ){   GLuint bitmask = 0;   /* Make a bitmask indicating what material attribute(s) we're updating */   switch (pname) {      case GL_EMISSION:         bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;         break;      case GL_AMBIENT:         bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;         break;      case GL_DIFFUSE:         bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;         break;      case GL_SPECULAR:         bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;         break;      case GL_SHININESS:         bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;         break;      case GL_AMBIENT_AND_DIFFUSE:         bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;         bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;         break;      case GL_COLOR_INDEXES:         bitmask |= MAT_BIT_FRONT_INDEXES  | MAT_BIT_BACK_INDEXES;         break;      default:         _mesa_error( ctx, GL_INVALID_ENUM, where );         return 0;   }   if (face==GL_FRONT) {      bitmask &= FRONT_MATERIAL_BITS;   }   else if (face==GL_BACK) {      bitmask &= BACK_MATERIAL_BITS;   }   else if (face != GL_FRONT_AND_BACK) {      _mesa_error( ctx, GL_INVALID_ENUM, where );      return 0;   }   if (bitmask & ~legal) {      _mesa_error( ctx, GL_INVALID_ENUM, where );      return 0;   }   return bitmask;}/* Perform a straight copy between materials. */void_mesa_copy_materials( struct gl_material *dst,                      const struct gl_material *src,                      GLuint bitmask ){   int i;   for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)       if (bitmask & (1<<i))	 COPY_4FV( dst->Attrib[i], src->Attrib[i] );}/* Update derived values following a change in ctx->Light.Material */void_mesa_update_material( GLcontext *ctx, GLuint bitmask ){   struct gl_light *light, *list = &ctx->Light.EnabledList;   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)       _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);   if (!bitmask)      return;   /* update material ambience */   if (bitmask & MAT_BIT_FRONT_AMBIENT) {      foreach (light, list) {         SCALE_3V( light->_MatAmbient[0], light->Ambient, 		   mat[MAT_ATTRIB_FRONT_AMBIENT]);      }   }   if (bitmask & MAT_BIT_BACK_AMBIENT) {      foreach (light, list) {         SCALE_3V( light->_MatAmbient[1], light->Ambient, 		   mat[MAT_ATTRIB_BACK_AMBIENT]);      }   }   /* update BaseColor = emission + scene's ambience * material's ambience */   if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {      COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );      ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],		    ctx->Light.Model.Ambient );   }   if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {      COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );      ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],		    ctx->Light.Model.Ambient );   }   /* update material diffuse values */   if (bitmask & MAT_BIT_FRONT_DIFFUSE) {      foreach (light, list) {	 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, 		   mat[MAT_ATTRIB_FRONT_DIFFUSE] );      }   }   if (bitmask & MAT_BIT_BACK_DIFFUSE) {      foreach (light, list) {	 SCALE_3V( light->_MatDiffuse[1], light->Diffuse, 		   mat[MAT_ATTRIB_BACK_DIFFUSE] );      }   }   /* update material specular values */   if (bitmask & MAT_BIT_FRONT_SPECULAR) {      foreach (light, list) {	 SCALE_3V( light->_MatSpecular[0], light->Specular, 		   mat[MAT_ATTRIB_FRONT_SPECULAR]);      }   }   if (bitmask & MAT_BIT_BACK_SPECULAR) {      foreach (light, list) {	 SCALE_3V( light->_MatSpecular[1], light->Specular,		   mat[MAT_ATTRIB_BACK_SPECULAR]);      }   }   if (bitmask & MAT_BIT_FRONT_SHININESS) {      _mesa_invalidate_shine_table( ctx, 0 );   }   if (bitmask & MAT_BIT_BACK_SHININESS) {      _mesa_invalidate_shine_table( ctx, 1 );   }}/* * Update the current materials from the given rgba color * according to the bitmask in ColorMaterialBitmask, which is * set by glColorMaterial(). */void_mesa_update_color_material( GLcontext *ctx, const GLfloat color[4] ){   GLuint bitmask = ctx->Light.ColorMaterialBitmask;   struct gl_material *mat = &ctx->Light.Material;   int i;   for (i = 0 ; i < MAT_ATTRIB_MAX ; i++)       if (bitmask & (1<<i))	 COPY_4FV( mat->Attrib[i], color );   _mesa_update_material( ctx, bitmask );}void GLAPIENTRY_mesa_ColorMaterial( GLenum face, GLenum mode ){   GET_CURRENT_CONTEXT(ctx);   GLuint bitmask;   GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |		   MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |		   MAT_BIT_FRONT_DIFFUSE  | MAT_BIT_BACK_DIFFUSE  |		   MAT_BIT_FRONT_AMBIENT  | MAT_BIT_BACK_AMBIENT);   ASSERT_OUTSIDE_BEGIN_END(ctx);   if (MESA_VERBOSE&VERBOSE_API)      _mesa_debug(ctx, "glColorMaterial %s %s\n",                  _mesa_lookup_enum_by_nr(face),                  _mesa_lookup_enum_by_nr(mode));   bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");   if (ctx->Light.ColorMaterialBitmask == bitmask &&       ctx->Light.ColorMaterialFace == face &&       ctx->Light.ColorMaterialMode == mode)      return;   FLUSH_VERTICES(ctx, _NEW_LIGHT);   ctx->Light.ColorMaterialBitmask = bitmask;   ctx->Light.ColorMaterialFace = face;   ctx->Light.ColorMaterialMode = mode;   if (ctx->Light.ColorMaterialEnabled) {      FLUSH_CURRENT( ctx, 0 );      _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);   }   if (ctx->Driver.ColorMaterial)      ctx->Driver.ColorMaterial( ctx, face, mode );}void GLAPIENTRY_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ){   GET_CURRENT_CONTEXT(ctx);   GLuint f;   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */   FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */   if (face==GL_FRONT) {      f = 0;   }   else if (face==GL_BACK) {      f = 1;   }   else {      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );      return;   }   switch (pname) {      case GL_AMBIENT:         COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );         break;      case GL_DIFFUSE:         COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );	 break;      case GL_SPECULAR:         COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );	 break;      case GL_EMISSION:	 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );	 break;      case GL_SHININESS:	 *params = mat[MAT_ATTRIB_SHININESS(f)][0];	 break;      case GL_COLOR_INDEXES:	 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];	 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];	 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];	 break;      default:         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );   }}void GLAPIENTRY_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ){   GET_CURRENT_CONTEXT(ctx);   GLuint f;   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */   FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */   if (face==GL_FRONT) {      f = 0;   }   else if (face==GL_BACK) {      f = 1;   }   else {      _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );      return;   }   switch (pname) {      case GL_AMBIENT:         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );         break;      case GL_DIFFUSE:         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );	 break;      case GL_SPECULAR:         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );	 break;      case GL_EMISSION:         params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );         params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );         params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );         params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );	 break;      case GL_SHININESS:         *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] );	 break;      case GL_COLOR_INDEXES:	 params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] );	 params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] );	 params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] );	 break;      default:         _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );   }}/**********************************************************************//*****                  Lighting computation                      *****//**********************************************************************//* * Notes: *   When two-sided lighting is enabled we compute the color (or index) *   for both the front and back side of the primitive.  Then, when the *   orientation of the facet is later learned, we can determine which *   color (or index) to use for rendering. * *   KW: We now know orientation in advance and only shade for *       the side or sides which are actually required. * * Variables: *   n = normal vector *   V = vertex position *   P = light source position *   Pe = (0,0,0,1) * * Precomputed: *   IF P[3]==0 THEN *       // light at infinity *       IF local_viewer THEN *           _VP_inf_norm = unit vector from V to P      // Precompute *       ELSE *           // eye at infinity *           _h_inf_norm = Normalize( VP + <0,0,1> )     // Precompute *       ENDIF *   ENDIF * * Functions: *   Normalize( v ) = normalized vector v *   Magnitude( v ) = length of vector v *//* * Whenever the spotlight exponent for a light changes we must call * this function to recompute the exponent lookup table. */void_mesa_invalidate_spot_exp_table( struct gl_light *l ){   l->_SpotExpTable[0][0] = -1;}static voidvalidate_spot_exp_table( struct gl_light *l ){   GLint i;   GLdouble exponent = l->SpotExponent;   GLdouble tmp = 0;   GLint clamp = 0;   l->_SpotExpTable[0][0] = 0.0;   for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {      if (clamp == 0) {	 tmp = _mesa_pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);	 if (tmp < FLT_MIN * 100.0) {	    tmp = 0.0;	    clamp = 1;	 }      }      l->_SpotExpTable[i][0] = (GLfloat) tmp;   }   for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {      l->_SpotExpTable[i][1] = (l->_SpotExpTable[i+1][0] -				l->_SpotExpTable[i][0]);   }   l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;}/* Calculate a new shine table.  Doing this here saves a branch in

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -