changed the classic decal mode to the new one where decal does not over-write the poly color. It raises our minimum platform to be able to support three layers instead of two. Also I have added the interpolate (grass-path) mode. This mode uses the top most alpha file to determine whether to show bottom texture or top

This commit is contained in:
Asad M. Zaman 2006-01-27 00:47:29 +00:00
parent 669d2c5c50
commit 06b1837f77
3 changed files with 100 additions and 17 deletions

View File

@ -60,7 +60,9 @@ MayaShaderColorDef() {
_wrap_v = true;
_has_alpha_channel = false;
_keep_color = false; // classic mode overwrites color: new mode retains color with a 3rd layer
_keep_alpha = false;
_interpolate = false;
_blend_type = BT_unspecified;
@ -103,7 +105,9 @@ MayaShaderColorDef(MayaShaderColorDef &copy) {
_blend_type = copy._blend_type;
_has_alpha_channel = copy._has_alpha_channel;
_keep_color = copy._keep_color;
_keep_alpha = copy._keep_alpha;
_interpolate = copy._interpolate;
_repeat_uv = copy._repeat_uv;
_offset = copy._offset;
@ -374,6 +378,9 @@ read_surface_color(MayaShader *shader, MObject color, bool trans) {
switch (blendValue) {
case 1:
bt = BT_decal;
get_bool_attribute(color, "interpolate", _interpolate);
maya_cat.info() << "interpolate: " << _interpolate << endl;
_keep_color = true;
break;
case 6:
bt = BT_modulate;

View File

@ -96,7 +96,9 @@ public:
bool _wrap_v;
bool _has_alpha_channel;
bool _keep_color;
bool _keep_alpha;
bool _interpolate;
LVector2f _repeat_uv;
LVector2f _offset;

View File

@ -2319,22 +2319,32 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
// determine if the base texture or any of the top texture need to be rgb only
MayaShaderColorDef *color_def = NULL;
bool is_rgb = false;
bool is_decal = false;
bool is_interpolate = false;
int i;
for (i=0; i<(int)shader._color.size(); ++i) {
// last shader is the base so lets skip it
for (i=0; i<(int)shader._color.size()-1; ++i) {
color_def = shader.get_color_def(i);
if (color_def->_has_texture && i != (int)shader._color.size()-1) {
if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_modulate) {
// read the _has_alpha_cahnnel to figure out rgb or rgba
//if (!color_def->_has_alpha_channel) {
if (color_def->_has_texture) {
if ((EggTexture::EnvType)color_def->_interpolate) {
is_interpolate = true;
}
else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_modulate) {
// Maya's multiply is slightly different than panda's. Unless, _keep_alpha is set,
// we are dropping the alpha.
if (!color_def->_keep_alpha)
is_rgb = true; // modulate forces the alpha to be ignored
//}
}
else if ((EggTexture::EnvType)color_def->_blend_type == EggTexture::ET_decal) {
is_decal = true;
}
}
}
// new decal mode needs an extra dummy layers of textureStage
EggTexture *dummy_tex = (EggTexture *)NULL;
string dummy_uvset_name;
// In Maya, a polygon is either textured or colored. The texture,
// if present, replaces the color. Also now there could be multiple textures
const MayaShaderColorDef &trans_def = shader._transparency;
@ -2415,6 +2425,35 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
// last shader on the list is the base one, which should always pick up the alpha
// from the texture file. But the top textures may have to strip the alpha
if (i!=shader._color.size()-1) {
if (!i && is_interpolate) {
// this is the grass path mode where alpha on this texture determines
// whether to show layer1 or layer2. Since by now other layers are set
// lets change those to get this effect
tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_interpolate);
tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_previous);
tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_last_saved_result);
tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
tex.set_combine_source(EggTexture::CC_rgb, 2, EggTexture::CS_texture);
tex.set_combine_operand(EggTexture::CC_rgb, 2, EggTexture::CO_src_alpha);
tex.set_combine_mode(EggTexture::CC_alpha, EggTexture::CM_interpolate);
tex.set_combine_source(EggTexture::CC_alpha, 0, EggTexture::CS_previous);
tex.set_combine_operand(EggTexture::CC_alpha, 0, EggTexture::CO_src_alpha);
tex.set_combine_source(EggTexture::CC_alpha, 1, EggTexture::CS_last_saved_result);
tex.set_combine_operand(EggTexture::CC_alpha, 1, EggTexture::CO_src_alpha);
tex.set_combine_source(EggTexture::CC_alpha, 2, EggTexture::CS_texture);
tex.set_combine_operand(EggTexture::CC_alpha, 2, EggTexture::CO_src_alpha);
}
else {
if (is_interpolate) {
tex.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate);
tex.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color);
tex.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
tex.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_texture);
tex.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
}
else {
tex.set_env_type((EggTexture::EnvType)color_def->_blend_type);
if (tex.get_env_type() == EggTexture::ET_modulate) {
if (color_def->_has_alpha_channel) {
@ -2431,6 +2470,34 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
}
}
}
}
else {
if (is_interpolate) {
// base shader need to save result
tex.set_saved_result(true);
}
else if (is_decal) {
// decal in classic time, always overwrote the base color. That causes problem
// when the polygon wants to be lit or wants to retain vertex/polygon color
// In the new decal mode, we achieve this with a third dummy layer
// copy this layer to a new dummy layer
EggTexture texDummy(shader.get_name()+".dummy", "");
mayaegg_cat.debug() << "creating dummy shader: " << texDummy.get_name() << endl;
texDummy.set_filename(outpath);
texDummy.set_fullpath(fullpath);
apply_texture_properties(texDummy, *color_def);
texDummy.set_combine_mode(EggTexture::CC_rgb, EggTexture::CM_modulate);
texDummy.set_combine_source(EggTexture::CC_rgb, 0, EggTexture::CS_primary_color);
texDummy.set_combine_operand(EggTexture::CC_rgb, 0, EggTexture::CO_src_color);
texDummy.set_combine_source(EggTexture::CC_rgb, 1, EggTexture::CS_previous);
texDummy.set_combine_operand(EggTexture::CC_rgb, 1, EggTexture::CO_src_color);
dummy_tex = _textures.create_unique_texture(texDummy, ~0);
// make this layer ET_replace
tex.set_env_type(EggTexture::ET_replace);
}
}
}
} else { // trans_def._has_texture
// We have a texture on transparency only. Apply it as the
// primary filename, and set the format accordingly.
@ -2460,6 +2527,9 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
else
color_def->_uvset_name.assign(uvset_name.c_str());
new_tex->set_uv_name(color_def->_uvset_name);
if (i == (int)shader._color.size()-1 && is_decal) {
dummy_uvset_name.assign(color_def->_uvset_name);
}
}
} else {
primitive.add_texture(new_tex);
@ -2467,6 +2537,10 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader,
}
}
}
if (dummy_tex != (EggTexture *)NULL) {
primitive.add_texture(dummy_tex);
dummy_tex->set_uv_name(dummy_uvset_name);
}
// Also apply an overall color to the primitive.
Colorf rgba = shader.get_rgba();