I'm not sure on that global ambient function, I'll just assume (and since the lighting seems to be correct it looks to be a good guess) that the chip actually multiplies and adds the emissive and ambient material properties the way it should. Hard to be sure just by looking at the register defines ;-), maybe someone with documentation could comment?
One drawback unfortunately stays for now, the fallback with materials between begin/end. I've scratched my head, but really couldn't figure out how it could be eliminated (for neither the TCL and vtxfmt case). I guess I'll have to leave that to somebody else with more knowledge of the driver/chip (documentation probably wouldn't hurt neither). If you want to try your luck, I've also attached a simple testcase which fails if the fallback check is removed (yes it's a hacked fogcoord demo, without fog but with materials, just put it in the Mesa tests directory and add it to the Makefile).
(I had some idea not to eliminate the fallback, but make it more rare to happen, which could also help other chips such as the radeon. It seems to happen quite frequently that the material call isn't really inside the primitive, i.e. the code looks like this:
glBegin(GL_QUAD);
glMaterialfv(GL_FRONT, GL_AMBIENT, ambcolors);
glVertex3f(...);
glVertex3f(...);
...
glEnd;
Maybe it would be possible to detect those cases and avoid a fallback in that case. Or maybe that's just a crazy idea ;-).)
I've also changed the lighting for the radeon accordingly, at least I believe it should work the same, but maybe it doesn't... Even if it works though it won't help much since it's impossible to eliminate the two-side fallback. It's also possible it slows down everything, I'm not sure if the radeon tcl unit is really that fast. Anyway, it's completely untested, use at your own risk (I'll try it out over the weekend possibly).
Roland
? server/cvs
Index: radeon_state.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_state.c,v
retrieving revision 1.14
diff -w -u -r1.14 radeon_state.c
--- radeon_state.c 2 Feb 2004 21:26:40 -0000 1.14
+++ radeon_state.c 7 Feb 2004 00:59:49 -0000
@@ -773,6 +773,7 @@
float *fcmd = (float *)RADEON_DB_STATE( glt );
/* Need to do more if both emmissive & ambient are PREMULT:
+ * Hope this is not needed for MULT
*/
if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
@@ -795,9 +796,6 @@
/* Update on change to
* - light[p].colors
* - light[p].enabled
- * - material,
- * - colormaterial enabled
- * - colormaterial bitmask
*/
static void update_light_colors( GLcontext *ctx, GLuint p )
{
@@ -808,25 +806,11 @@
if (l->Enabled) {
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
- GLuint bitmask = ctx->Light.ColorMaterialBitmask;
- GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
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 & MAT_BIT_FRONT_AMBIENT) == 0)
- SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat[MAT_ATTRIB_FRONT_AMBIENT] );
-
- if ((bitmask & MAT_BIT_FRONT_DIFFUSE) == 0)
- SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat[MAT_ATTRIB_FRONT_DIFFUSE] );
-
- if ((bitmask & MAT_BIT_FRONT_SPECULAR) == 0)
- SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat[MAT_ATTRIB_FRONT_SPECULAR] );
-
RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
}
}
@@ -860,51 +844,66 @@
static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
{
- if (ctx->Light.ColorMaterialEnabled) {
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
- GLuint mask = ctx->Light.ColorMaterialBitmask;
- /* Default to PREMULT:
- */
light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
(3 << RADEON_AMBIENT_SOURCE_SHIFT) |
(3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
(3 << RADEON_SPECULAR_SOURCE_SHIFT));
+ if (ctx->Light.ColorMaterialEnabled) {
+ GLuint mask = ctx->Light.ColorMaterialBitmask;
+
if (mask & MAT_BIT_FRONT_EMISSION) {
light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_EMISSIVE_SOURCE_SHIFT);
}
+ else {
+ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
+ RADEON_EMISSIVE_SOURCE_SHIFT);
+ }
if (mask & MAT_BIT_FRONT_AMBIENT) {
light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_AMBIENT_SOURCE_SHIFT);
}
+ else {
+ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
+ RADEON_AMBIENT_SOURCE_SHIFT);
+ }
if (mask & MAT_BIT_FRONT_DIFFUSE) {
light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_DIFFUSE_SOURCE_SHIFT);
}
+ else {
+ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
+ RADEON_DIFFUSE_SOURCE_SHIFT);
+ }
if (mask & MAT_BIT_FRONT_SPECULAR) {
light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
RADEON_SPECULAR_SOURCE_SHIFT);
}
+ else {
+ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
+ RADEON_SPECULAR_SOURCE_SHIFT);
+ }
+ }
+ else {
+ /* Default to MULT:
+ */
+ light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
RADEON_EMISSIVE_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
+ }
if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
- GLuint p;
-
RADEON_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
-
- for (p = 0 ; p < MAX_LIGHTS; p++)
- update_light_colors( ctx, p );
- update_global_ambient( ctx );
- }
}
-
- check_twoside_fallback( ctx );
}
void radeonUpdateMaterial( GLcontext *ctx )
@@ -912,7 +911,6 @@
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
- GLuint p;
GLuint mask = ~0;
if (ctx->Light.ColorMaterialEnabled)
@@ -952,11 +950,8 @@
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 );
+/* update_global_ambient( ctx );*/
}
/* _NEW_LIGHT
Index: radeon_state_init.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/radeon/radeon_state_init.c,v
retrieving revision 1.5
diff -w -u -r1.5 radeon_state_init.c
--- radeon_state_init.c 23 Jan 2004 03:19:47 -0000 1.5
+++ radeon_state_init.c 7 Feb 2004 00:59:52 -0000
@@ -499,10 +499,10 @@
(RADEON_SPECULAR_LIGHTS |
RADEON_DIFFUSE_SPECULAR_COMBINE |
RADEON_LOCAL_LIGHT_VEC_GL |
- (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
- (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_AMBIENT_SOURCE_SHIFT) |
- (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
- (RADEON_LM_SOURCE_STATE_PREMULT << RADEON_SPECULAR_SOURCE_SHIFT));
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
+ (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT));
for (i = 0 ; i < 8; i++) {
struct gl_light *l = &ctx->Light.Light[i];
? server
Index: r200_state.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_state.c,v
retrieving revision 1.13
diff -w -u -r1.13 r200_state.c
--- r200_state.c 27 Jan 2004 18:52:40 -0000 1.13
+++ r200_state.c 7 Feb 2004 00:56:36 -0000
@@ -786,6 +786,8 @@
float *fcmd = (float *)R200_DB_STATE( glt );
/* Need to do more if both emmissive & ambient are PREMULT:
+ * I believe this is not nessary when using source_material. This condition thus
+ * will never happen currently, and the function has no dependencies on materials
now
*/
if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
@@ -808,9 +810,6 @@
/* Update on change to
* - light[p].colors
* - light[p].enabled
- * - material,
- * - colormaterial enabled
- * - colormaterial bitmask
*/
static void update_light_colors( GLcontext *ctx, GLuint p )
{
@@ -821,102 +820,115 @@
if (l->Enabled) {
r200ContextPtr rmesa = R200_CONTEXT(ctx);
float *fcmd = (float *)R200_DB_STATE( lit[p] );
- GLuint bitmask = ctx->Light.ColorMaterialBitmask;
- GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
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 & MAT_BIT_FRONT_AMBIENT) == 0)
- SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat[MAT_ATTRIB_FRONT_AMBIENT] );
-
- if ((bitmask & MAT_BIT_FRONT_DIFFUSE) == 0)
- SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat[MAT_ATTRIB_FRONT_DIFFUSE] );
-
- if ((bitmask & MAT_BIT_FRONT_SPECULAR) == 0)
- SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat[MAT_ATTRIB_FRONT_SPECULAR] );
-
R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
}
}
-/* Also fallback for asym colormaterial mode in twoside lighting...
- */
-static void check_twoside_fallback( GLcontext *ctx )
-{
- GLboolean fallback = GL_FALSE;
- GLint i;
-
- if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
- if (ctx->Light.ColorMaterialEnabled &&
- (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
- ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
- fallback = GL_TRUE;
- else {
- for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
- if (memcmp( ctx->Light.Material.Attrib[i],
- ctx->Light.Material.Attrib[i+1],
- sizeof(GLfloat)*4) != 0) {
- fallback = GL_TRUE;
- break;
- }
- }
- }
-
- TCL_FALLBACK( ctx, R200_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
-}
-
static void r200ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
{
- if (ctx->Light.ColorMaterialEnabled) {
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1];
- GLuint mask = ctx->Light.ColorMaterialBitmask;
-
- /* Default to PREMULT:
- */
light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
(0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
(0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
- (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT));
+ (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
+ (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
+ (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) |
+ (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
+ (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT));
+
+ if (ctx->Light.ColorMaterialEnabled) {
+ GLuint mask = ctx->Light.ColorMaterialBitmask;
if (mask & MAT_BIT_FRONT_EMISSION) {
light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
R200_FRONT_EMISSIVE_SOURCE_SHIFT);
}
+ else
+ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
+ R200_FRONT_EMISSIVE_SOURCE_SHIFT);
if (mask & MAT_BIT_FRONT_AMBIENT) {
light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
R200_FRONT_AMBIENT_SOURCE_SHIFT);
}
+ else
+ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
+ R200_FRONT_AMBIENT_SOURCE_SHIFT);
if (mask & MAT_BIT_FRONT_DIFFUSE) {
light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
R200_FRONT_DIFFUSE_SOURCE_SHIFT);
}
+ else
+ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
+ R200_FRONT_DIFFUSE_SOURCE_SHIFT);
if (mask & MAT_BIT_FRONT_SPECULAR) {
light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
R200_FRONT_SPECULAR_SOURCE_SHIFT);
}
+ else {
+ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
+ R200_FRONT_SPECULAR_SOURCE_SHIFT);
+ }
- if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
- GLuint p;
+ if (mask & MAT_BIT_BACK_EMISSION) {
+ light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
+ R200_BACK_EMISSIVE_SOURCE_SHIFT);
+ }
- R200_STATECHANGE( rmesa, tcl );
- rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
+ else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
+ R200_BACK_EMISSIVE_SOURCE_SHIFT);
- for (p = 0 ; p < MAX_LIGHTS; p++)
- update_light_colors( ctx, p );
- update_global_ambient( ctx );
+ if (mask & MAT_BIT_BACK_AMBIENT) {
+ light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
+ R200_BACK_AMBIENT_SOURCE_SHIFT);
}
+ else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
+ R200_BACK_AMBIENT_SOURCE_SHIFT);
+
+ if (mask & MAT_BIT_BACK_DIFFUSE) {
+ light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
+ R200_BACK_DIFFUSE_SOURCE_SHIFT);
}
+ else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
+ R200_BACK_DIFFUSE_SOURCE_SHIFT);
+
+ if (mask & MAT_BIT_BACK_SPECULAR) {
+ light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
+ R200_BACK_SPECULAR_SOURCE_SHIFT);
+ }
+ else {
+ light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
+ R200_BACK_SPECULAR_SOURCE_SHIFT);
+ }
+ }
+ else {
+ /* Default to SOURCE_MATERIAL:
+ */
+ light_model_ctl1 |=
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT);
+ }
+
+ if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
+ R200_STATECHANGE( rmesa, tcl );
+ rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
+ }
+
- check_twoside_fallback( ctx );
}
void r200UpdateMaterial( GLcontext *ctx )
@@ -924,16 +936,16 @@
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] );
- GLuint p;
+ GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] );
GLuint mask = ~0;
+ /* Might be possible and faster to update everything unconditionally? */
if (ctx->Light.ColorMaterialEnabled)
mask &= ~ctx->Light.ColorMaterialBitmask;
if (R200_DEBUG & DEBUG_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
-
if (mask & MAT_BIT_FRONT_EMISSION) {
fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0];
fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
@@ -962,13 +974,39 @@
fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0];
}
- R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
+ if (mask & MAT_BIT_BACK_EMISSION) {
+ fcmd2[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_BACK_EMISSION][0];
+ fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1];
+ fcmd2[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_BACK_EMISSION][2];
+ fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3];
+ }
+ if (mask & MAT_BIT_BACK_AMBIENT) {
+ fcmd2[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_BACK_AMBIENT][0];
+ fcmd2[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_BACK_AMBIENT][1];
+ fcmd2[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_BACK_AMBIENT][2];
+ fcmd2[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_BACK_AMBIENT][3];
+ }
+ if (mask & MAT_BIT_BACK_DIFFUSE) {
+ fcmd2[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_BACK_DIFFUSE][0];
+ fcmd2[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_BACK_DIFFUSE][1];
+ fcmd2[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_BACK_DIFFUSE][2];
+ fcmd2[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_BACK_DIFFUSE][3];
+ }
+ if (mask & MAT_BIT_BACK_SPECULAR) {
+ fcmd2[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_BACK_SPECULAR][0];
+ fcmd2[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_BACK_SPECULAR][1];
+ fcmd2[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_BACK_SPECULAR][2];
+ fcmd2[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_BACK_SPECULAR][3];
+ }
+ if (mask & MAT_BIT_BACK_SHININESS) {
+ fcmd2[MTL_SHININESS] = mat[MAT_ATTRIB_BACK_SHININESS][0];
+ }
- for (p = 0 ; p < MAX_LIGHTS; p++)
- update_light_colors( ctx, p );
+ R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
+ R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] );
- check_twoside_fallback( ctx );
- update_global_ambient( ctx );
+ /* currently material changes cannot trigger a global ambient change, I believe
this is correct
+ update_global_ambient( ctx ); */
}
/* _NEW_LIGHT
@@ -1185,10 +1223,7 @@
if (ctx->Light.Model.TwoSide)
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
else
- rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHT_TWOSIDE;
-
- check_twoside_fallback( ctx );
-
+ rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
if (rmesa->TclFallback) {
r200ChooseRenderState( ctx );
r200ChooseVertexState( ctx );
@@ -1809,7 +1844,6 @@
case GL_LIGHTING:
r200UpdateSpecular(ctx);
- check_twoside_fallback( ctx );
break;
case GL_LINE_SMOOTH:
@@ -2131,7 +2165,7 @@
}
/* A hack. The r200 can actually cope just fine with materials
- * between begin/ends, so fix this.
+ * between begin/ends, so fix this. But how ?
*/
static GLboolean check_material( GLcontext *ctx )
{
@@ -2148,7 +2182,6 @@
return GL_FALSE;
}
-
static void r200WrapRunPipeline( GLcontext *ctx )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
Index: r200_state_init.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_state_init.c,v
retrieving revision 1.7
diff -w -u -r1.7 r200_state_init.c
--- r200_state_init.c 23 Jan 2004 03:19:47 -0000 1.7
+++ r200_state_init.c 7 Feb 2004 00:56:39 -0000
@@ -247,6 +247,7 @@
ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 );
ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 );
ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 );
+ ALLOC_STATE( mtl[1], tcl_lighting, MTL_STATE_SIZE, "MTL1/material1", 1 );
ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 );
ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 );
ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 );
@@ -318,6 +319,11 @@
cmdvec( R200_VS_MAT_0_EMISS, 1, 16 );
rmesa->hw.mtl[0].cmd[MTL_CMD_1] =
cmdscl2( R200_SS_MAT_0_SHININESS, 1, 1 );
+ rmesa->hw.mtl[1].cmd[MTL_CMD_0] =
+ cmdvec( R200_VS_MAT_1_EMISS, 1, 16 );
+ rmesa->hw.mtl[1].cmd[MTL_CMD_1] =
+ cmdscl2( R200_SS_MAT_1_SHININESS, 1, 1 );
+
rmesa->hw.grd.cmd[GRD_CMD_0] =
cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 );
rmesa->hw.fog.cmd[FOG_CMD_0] =
@@ -622,17 +628,19 @@
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] =
(R200_SPECULAR_LIGHTS |
R200_DIFFUSE_SPECULAR_COMBINE |
- R200_LOCAL_LIGHT_VEC_GL);
+ R200_LOCAL_LIGHT_VEC_GL |
+ R200_LM0_SOURCE_MATERIAL_0 << R200_FRONT_SHININESS_SOURCE_SHIFT |
+ R200_LM0_SOURCE_MATERIAL_1 << R200_BACK_SHININESS_SOURCE_SHIFT);
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] =
- ((R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_AMBIENT_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
- (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_SPECULAR_SOURCE_SHIFT));
+ ((R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
+ (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT));
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_0] = 0; /* filled in via callbacks */
rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_1] = 0;
/* * Exercise GL_EXT_fog_coord */
#define GL_GLEXT_PROTOTYPES
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
static int Width = 600;
static int Height = 200;
static GLfloat Near = 5.0, Far = 25.0;
GLfloat light0Pos[4] =
{0.3, 0.3, 0.0, 1.0};
GLfloat lightColor[4] = {1.0, 1.0, 1.0, 1.0};
static GLfloat matparam[6][4] = { {1.0, 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 1.0, 1.0 },
{ 0.0, 0.0, 0.0, 1.0 },
{ 1.0, 1.0, 1.0, 1.0 },
{ 1.0, 0.0, 0.0, 1.0 }};
static void Display( void )
{
GLint t;
glClearColor(0.2, 0.2, 0.8, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
for (t = 0; t <= 4; t ++) {
glMaterialfv(GL_FRONT, GL_AMBIENT, matparam[t]);
glPushMatrix();
glMaterialfv(GL_FRONT, GL_AMBIENT, matparam[t]);
glTranslatef(t * 2.5 - 5.0, 0, 0);
glBegin(GL_POLYGON);
glVertex2f(-1, -1);
glVertex2f( 1, -1);
glMaterialfv(GL_FRONT, GL_AMBIENT, matparam[t + 1]);
glVertex2f( 1, 1);
glVertex2f(-1, 1);
glEnd();
glPopMatrix();
}
glutSwapBuffers();
}
static void Reshape( int width, int height )
{
GLfloat ar = (float) width / (float) height;
Width = width;
Height = height;
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, -15.0 );
}
static void Key( unsigned char key, int x, int y )
{
(void) x;
(void) y;
switch (key) {
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
static void Init( void )
{
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightColor);
glEnable(GL_LIGHTING);
printf("Squares should be colored red/green green/blue blue/black black/white
white/red.\n");
}
int main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( Width, Height );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow(argv[0]);
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutDisplayFunc( Display );
Init();
glutMainLoop();
return 0;
}
