Fix some bugs in the shader generator regarding combine modes.

This commit is contained in:
rdb 2009-07-13 11:37:11 +00:00
parent 39c1cb42c9
commit 87e5347a1e
4 changed files with 115 additions and 45 deletions

View File

@ -627,6 +627,18 @@ get_combine_alpha_operand2() const {
return _combine_alpha_operand2;
}
////////////////////////////////////////////////////////////////////
// Function: TextureStage::involves_color_scale
// Access: Published
// Description: Returns true if the TextureStage is affected by the
// setting of the current ColorScaleAttrib, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool TextureStage::
involves_color_scale() const {
return _involves_color_scale;
}
////////////////////////////////////////////////////////////////////
// Function: TextureStage::uses_color
// Access: Published
@ -640,15 +652,25 @@ uses_color() const {
}
////////////////////////////////////////////////////////////////////
// Function: TextureStage::involves_color_scale
// Function: TextureStage::uses_primary_color
// Access: Published
// Description: Returns true if the TextureStage is affected by the
// setting of the current ColorScaleAttrib, false
// otherwise.
// Description: Returns true if the TextureStage makes use of
// the CS_primary_color combine source.
////////////////////////////////////////////////////////////////////
INLINE bool TextureStage::
involves_color_scale() const {
return _involves_color_scale;
uses_primary_color() const {
return _uses_primary_color;
}
////////////////////////////////////////////////////////////////////
// Function: TextureStage::uses_last_saved_result
// Access: Published
// Description: Returns true if the TextureStage makes use of
// the CS_primary_color combine source.
////////////////////////////////////////////////////////////////////
INLINE bool TextureStage::
uses_last_saved_result() const {
return _uses_last_saved_result;
}
////////////////////////////////////////////////////////////////////
@ -684,7 +706,8 @@ get_sort_seq() {
////////////////////////////////////////////////////////////////////
// Function: TextureStage::update_color_flags
// Access: Private
// Description: Updates _uses_color and _involves_color_scale
// Description: Updates _uses_color, _involves_color_scale,
// _uses_primary_color and _uses_last_saved_result
// appropriately.
////////////////////////////////////////////////////////////////////
INLINE void TextureStage::
@ -709,6 +732,24 @@ update_color_flags() {
_combine_alpha_source0 == CS_constant ||
_combine_alpha_source1 == CS_constant ||
_combine_alpha_source2 == CS_constant)));
_uses_primary_color =
(_mode == M_combine &&
(_combine_rgb_source0 == CS_primary_color ||
_combine_rgb_source1 == CS_primary_color ||
_combine_rgb_source2 == CS_primary_color ||
_combine_alpha_source0 == CS_primary_color ||
_combine_alpha_source1 == CS_primary_color ||
_combine_alpha_source2 == CS_primary_color));
_uses_last_saved_result =
(_mode == M_combine &&
(_combine_rgb_source0 == CS_last_saved_result ||
_combine_rgb_source1 == CS_last_saved_result ||
_combine_rgb_source2 == CS_last_saved_result ||
_combine_alpha_source0 == CS_last_saved_result ||
_combine_alpha_source1 == CS_last_saved_result ||
_combine_alpha_source2 == CS_last_saved_result));
}
INLINE ostream &

View File

@ -168,8 +168,10 @@ PUBLISHED:
INLINE CombineSource get_combine_alpha_source2() const;
INLINE CombineOperand get_combine_alpha_operand2() const;
INLINE bool uses_color() const;
INLINE bool involves_color_scale() const;
INLINE bool uses_color() const;
INLINE bool uses_primary_color() const;
INLINE bool uses_last_saved_result() const;
void write(ostream &out) const;
void output(ostream &out) const;
@ -195,8 +197,10 @@ private:
int _rgb_scale;
int _alpha_scale;
bool _saved_result;
bool _uses_color;
bool _involves_color_scale;
bool _uses_color;
bool _uses_primary_color;
bool _uses_last_saved_result;
CombineMode _combine_rgb_mode;
int _num_combine_rgb_operands;

View File

@ -1127,8 +1127,21 @@ synthesize_shader(const RenderState *rs) {
}
}
text << "\t float4 primary_color = result;\n";
// Loop first to see if something is using primary_color or last_saved_result.
bool have_saved_result = false;
for (int i=0; i<_num_textures; i++) {
TextureStage *stage = texture->get_on_stage(i);
if (stage->get_mode() != TextureStage::M_combine) continue;
if (stage->uses_primary_color()) {
text << "\t float4 primary_color = result;\n";
}
if (stage->uses_last_saved_result()) {
text << "\t float4 last_saved_result = result;\n";
have_saved_result = true;
}
}
// Now loop through the textures to compose our magic blending formulas.
for (int i=0; i<_num_textures; i++) {
TextureStage *stage = texture->get_on_stage(i);
switch (stage->get_mode()) {
@ -1167,13 +1180,8 @@ synthesize_shader(const RenderState *rs) {
default:
break;
}
if (stage->get_saved_result()) {
if (have_saved_result) {
text << "\t last_saved_result = result;\n";
} else {
text << "\t float4 last_saved_result = result;\n";
have_saved_result = true;
}
if (stage->get_saved_result() && have_saved_result) {
text << "\t last_saved_result = result;\n";
}
}
// Apply the color scale.
@ -1265,35 +1273,35 @@ synthesize_shader(const RenderState *rs) {
// Description: This 'synthesizes' a combine mode into a string.
////////////////////////////////////////////////////////////////////
const string ShaderGenerator::
combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool single_value, short texindex) {
combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode, bool alpha, short texindex) {
ostringstream text;
switch (c_mode) {
case TextureStage::CM_modulate:
text << combine_source_as_string(stage, 0, single_value, texindex);
text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
text << " * ";
text << combine_source_as_string(stage, 1, single_value, texindex);
text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
break;
case TextureStage::CM_add:
text << combine_source_as_string(stage, 0, single_value, texindex);
text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
text << " + ";
text << combine_source_as_string(stage, 1, single_value, texindex);
text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
break;
case TextureStage::CM_add_signed:
pgraph_cat.error() << "TextureStage::CombineMode ADD_SIGNED not yet supported in per-pixel mode.\n";
break;
case TextureStage::CM_interpolate:
text << "lerp(";
text << combine_source_as_string(stage, 1, single_value, texindex);
text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
text << ", ";
text << combine_source_as_string(stage, 0, single_value, texindex);
text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
text << ", ";
text << combine_source_as_string(stage, 2, true, texindex);
text << combine_source_as_string(stage, 2, alpha, true, texindex);
text << ")";
break;
case TextureStage::CM_subtract:
text << combine_source_as_string(stage, 0, single_value, texindex);
text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
text << " + ";
text << combine_source_as_string(stage, 1, single_value, texindex);
text << combine_source_as_string(stage, 1, alpha, alpha, texindex);
break;
case TextureStage::CM_dot3_rgb:
pgraph_cat.error() << "TextureStage::CombineMode DOT3_RGB not yet supported in per-pixel mode.\n";
@ -1303,7 +1311,7 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode
break;
case TextureStage::CM_replace:
default: // Not sure if this is correct as default value.
text << combine_source_as_string(stage, 0, single_value, texindex);
text << combine_source_as_string(stage, 0, alpha, alpha, texindex);
break;
}
return text.str();
@ -1315,22 +1323,39 @@ combine_mode_as_string(CPT(TextureStage) stage, TextureStage::CombineMode c_mode
// Description: This 'synthesizes' a combine source into a string.
////////////////////////////////////////////////////////////////////
const string ShaderGenerator::
combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value, short texindex) {
combine_source_as_string(CPT(TextureStage) stage, short num, bool alpha, bool single_value, short texindex) {
TextureStage::CombineSource c_src = TextureStage::CS_undefined;
TextureStage::CombineOperand c_op = TextureStage::CO_undefined;
switch (num) {
case 0:
c_src = stage->get_combine_rgb_source0();
c_op = stage->get_combine_rgb_operand0();
break;
case 1:
c_src = stage->get_combine_rgb_source1();
c_op = stage->get_combine_rgb_operand1();
break;
case 2:
c_src = stage->get_combine_rgb_source2();
c_op = stage->get_combine_rgb_operand2();
break;
if (alpha) {
switch (num) {
case 0:
c_src = stage->get_combine_alpha_source0();
c_op = stage->get_combine_alpha_operand0();
break;
case 1:
c_src = stage->get_combine_alpha_source1();
c_op = stage->get_combine_alpha_operand1();
break;
case 2:
c_src = stage->get_combine_alpha_source2();
c_op = stage->get_combine_alpha_operand2();
break;
}
} else {
switch (num) {
case 0:
c_src = stage->get_combine_rgb_source0();
c_op = stage->get_combine_rgb_operand0();
break;
case 1:
c_src = stage->get_combine_rgb_source1();
c_op = stage->get_combine_rgb_operand1();
break;
case 2:
c_src = stage->get_combine_rgb_source2();
c_op = stage->get_combine_rgb_operand2();
break;
}
}
ostringstream csource;
if (c_op == TextureStage::CO_one_minus_src_color ||
@ -1368,7 +1393,7 @@ combine_source_as_string(CPT(TextureStage) stage, short num, bool single_value,
} else {
csource << ".a";
if (!single_value) {
// Dunno if it's legal at all, but let's just allow it.
// Dunno if it's legal in the FPP at all, but let's just allow it.
return "float3(" + csource.str() + ")";
}
}

View File

@ -73,9 +73,9 @@ protected:
CPT(RenderAttrib) create_shader_attrib(const string &txt);
PT(Texture) update_shadow_buffer(NodePath light_np);
static const string combine_mode_as_string(CPT(TextureStage) stage,
TextureStage::CombineMode c_mode, bool single_value, short texindex);
TextureStage::CombineMode c_mode, bool alpha, short texindex);
static const string combine_source_as_string(CPT(TextureStage) stage,
short num, bool single_value, short texindex);
short num, bool alpha, bool single_value, short texindex);
static const string texture_type_as_string(Texture::TextureType ttype);
// Shader register allocation: