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

📄 radeon_lighting.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.5 2002/09/16 18:05:20 eich Exp $ *//* * Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California. * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * Authors: *    Gareth Hughes <gareth@valinux.com> *    Keith Whitwell <keith@tungstengraphics.com> */#include "glheader.h"#include "imports.h"#include "api_arrayelt.h"/* #include "mmath.h" */#include "enums.h"#include "colormac.h"#include "radeon_context.h"#include "radeon_ioctl.h"#include "radeon_state.h"#include "radeon_tcl.h"#include "radeon_tex.h"#include "radeon_vtxfmt.h"/* ============================================================= * Materials *//* Update on colormaterial, material emmissive/ambient,  * lightmodel.globalambient */void update_global_ambient( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   float *fcmd = (float *)RADEON_DB_STATE( glt );   /* Need to do more if both emmissive & ambient are PREMULT:    */   if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &       ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |	(3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)    {      COPY_3V( &fcmd[GLT_RED], 	       ctx->Light.Material[0].Emission);      ACC_SCALE_3V( &fcmd[GLT_RED],		   ctx->Light.Model.Ambient,		   ctx->Light.Material[0].Ambient);   }    else   {      COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );   }      RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);}/* Update on change to  *    - light[p].colors *    - light[p].enabled *    - material, *    - colormaterial enabled *    - colormaterial bitmask */void update_light_colors( GLcontext *ctx, GLuint p ){   struct gl_light *l = &ctx->Light.Light[p];/*     fprintf(stderr, "%s\n", __FUNCTION__); */   if (l->Enabled) {      radeonContextPtr rmesa = RADEON_CONTEXT(ctx);      float *fcmd = (float *)RADEON_DB_STATE( lit[p] );      GLuint bitmask = ctx->Light.ColorMaterialBitmask;      struct gl_material *mat = &ctx->Light.Material[0];      COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );	       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );      COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );            if (!ctx->Light.ColorMaterialEnabled)	 bitmask = 0;      if ((bitmask & FRONT_AMBIENT_BIT) == 0) 	 SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat->Ambient );      if ((bitmask & FRONT_DIFFUSE_BIT) == 0) 	 SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat->Diffuse );            if ((bitmask & FRONT_SPECULAR_BIT) == 0) 	 SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat->Specular );      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );   }}/* Also fallback for asym colormaterial mode in twoside lighting... */void check_twoside_fallback( GLcontext *ctx ){   GLboolean fallback = GL_FALSE;   if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {      if (memcmp( &ctx->Light.Material[0],		  &ctx->Light.Material[1],		  sizeof(struct gl_material)) != 0)	 fallback = GL_TRUE;        else if (ctx->Light.ColorMaterialEnabled &&	       (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != 	       ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))	 fallback = GL_TRUE;   }   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );}void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ){   if (ctx->Light.ColorMaterialEnabled) {      radeonContextPtr rmesa = RADEON_CONTEXT(ctx);      GLuint light_model_ctl = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];      GLuint mask = ctx->Light.ColorMaterialBitmask;      /* Default to PREMULT:       */      light_model_ctl &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |			   (3 << RADEON_AMBIENT_SOURCE_SHIFT) |			   (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |			   (3 << RADEON_SPECULAR_SOURCE_SHIFT));          if (mask & FRONT_EMISSION_BIT) {	 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_EMISSIVE_SOURCE_SHIFT);      }      if (mask & FRONT_AMBIENT_BIT) {	 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_AMBIENT_SOURCE_SHIFT);      }	       if (mask & FRONT_DIFFUSE_BIT) {	 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_DIFFUSE_SOURCE_SHIFT);      }         if (mask & FRONT_SPECULAR_BIT) {	 light_model_ctl |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<			     RADEON_SPECULAR_SOURCE_SHIFT);      }         if (light_model_ctl != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {	 GLuint p;	 RADEON_STATECHANGE( rmesa, tcl );	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl;      	 for (p = 0 ; p < MAX_LIGHTS; p++) 	    update_light_colors( ctx, p );	 update_global_ambient( ctx );      }   }      check_twoside_fallback( ctx );}void radeonUpdateMaterial( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );   GLuint p;   GLuint mask = ~0;      if (ctx->Light.ColorMaterialEnabled)      mask &= ~ctx->Light.ColorMaterialBitmask;   if (RADEON_DEBUG & DEBUG_STATE)      fprintf(stderr, "%s\n", __FUNCTION__);         if (mask & FRONT_EMISSION_BIT) {      fcmd[MTL_EMMISSIVE_RED]   = ctx->Light.Material[0].Emission[0];      fcmd[MTL_EMMISSIVE_GREEN] = ctx->Light.Material[0].Emission[1];      fcmd[MTL_EMMISSIVE_BLUE]  = ctx->Light.Material[0].Emission[2];      fcmd[MTL_EMMISSIVE_ALPHA] = ctx->Light.Material[0].Emission[3];   }   if (mask & FRONT_AMBIENT_BIT) {      fcmd[MTL_AMBIENT_RED]     = ctx->Light.Material[0].Ambient[0];      fcmd[MTL_AMBIENT_GREEN]   = ctx->Light.Material[0].Ambient[1];      fcmd[MTL_AMBIENT_BLUE]    = ctx->Light.Material[0].Ambient[2];      fcmd[MTL_AMBIENT_ALPHA]   = ctx->Light.Material[0].Ambient[3];   }   if (mask & FRONT_DIFFUSE_BIT) {      fcmd[MTL_DIFFUSE_RED]     = ctx->Light.Material[0].Diffuse[0];      fcmd[MTL_DIFFUSE_GREEN]   = ctx->Light.Material[0].Diffuse[1];      fcmd[MTL_DIFFUSE_BLUE]    = ctx->Light.Material[0].Diffuse[2];      fcmd[MTL_DIFFUSE_ALPHA]   = ctx->Light.Material[0].Diffuse[3];   }   if (mask & FRONT_SPECULAR_BIT) {      fcmd[MTL_SPECULAR_RED]    = ctx->Light.Material[0].Specular[0];      fcmd[MTL_SPECULAR_GREEN]  = ctx->Light.Material[0].Specular[1];      fcmd[MTL_SPECULAR_BLUE]   = ctx->Light.Material[0].Specular[2];      fcmd[MTL_SPECULAR_ALPHA]  = ctx->Light.Material[0].Specular[3];   }   if (mask & FRONT_SHININESS_BIT) {      fcmd[MTL_SHININESS]       = ctx->Light.Material[0].Shininess;   }   if (RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl )) {      for (p = 0 ; p < MAX_LIGHTS; p++) 	 update_light_colors( ctx, p );      check_twoside_fallback( ctx );      update_global_ambient( ctx );   }   else if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_STATE))      fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__);}/* _NEW_LIGHT * _NEW_MODELVIEW * _MESA_NEW_NEED_EYE_COORDS * * Uses derived state from mesa: *       _VP_inf_norm *       _h_inf_norm *       _Position *       _NormDirection *       _ModelViewInvScale *       _NeedEyeCoords *       _EyeZDir * * which are calculated in light.c and are correct for the current * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW * and _MESA_NEW_NEED_EYE_COORDS.   */void radeonUpdateLighting( GLcontext *ctx ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   /* Have to check these, or have an automatic shortcircuit mechanism    * to remove noop statechanges. (Or just do a better job on the    * front end).    */   {      GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];      if (ctx->_NeedEyeCoords)	 tmp &= ~RADEON_LIGHT_IN_MODELSPACE;      else	 tmp |= RADEON_LIGHT_IN_MODELSPACE;            /* Leave this test disabled: (unexplained q3 lockup) (even with         new packets)      */      if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])       {	 RADEON_STATECHANGE( rmesa, tcl );	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;      }   }   {      GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );      fcmd[EYE_X] = ctx->_EyeZDir[0];      fcmd[EYE_Y] = ctx->_EyeZDir[1];      fcmd[EYE_Z] = - ctx->_EyeZDir[2];      fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;      RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );   }/*     RADEON_STATECHANGE( rmesa, glt ); */   if (ctx->Light.Enabled) {      GLint p;      for (p = 0 ; p < MAX_LIGHTS; p++) {	 if (ctx->Light.Light[p].Enabled) {	    struct gl_light *l = &ctx->Light.Light[p];	    GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );	    	    if (l->EyePosition[3] == 0.0) {	       COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); 	       COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); 	       fcmd[LIT_POSITION_W] = 0;	       fcmd[LIT_DIRECTION_W] = 0;	    } else {	       COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );	       fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];	       fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];	       fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];	       fcmd[LIT_DIRECTION_W] = 0;	    }	    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );	 }      }   }}void radeonLightfv( GLcontext *ctx, GLenum light,		    GLenum pname, const GLfloat *params ){   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);   GLint p = light - GL_LIGHT0;   struct gl_light *l = &ctx->Light.Light[p];   GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;      switch (pname) {   case GL_AMBIENT:		   case GL_DIFFUSE:   case GL_SPECULAR:      update_light_colors( ctx, p );      break;   case GL_SPOT_DIRECTION:       /* picked up in update_light */	

⌨️ 快捷键说明

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