once again, thank you David for your help. I have finished doing more tests on this issue and my decision is that this is a bug in Panda3D since using any geometry with vertex or polygon color in the particle panel results in white geometry as is the case with c++ code. i don’t believe this was the intention of GeomParticleRenderer creator.
After some tests i came up with a solution which allows GeomParticleRenderer to use vertex color, flat color or whatever color attribute applied to the geomnode. The solution also works with geomnodes having mixed attributes ( some children have a flat color and others have vertex colors ). the results are very nice and are much better than using textures since no matter what scaling is applied quality is preserved.
I beleive the modifications should be added to Panda3D since they match more what is expected of the way GeomParticleRenderer should handle colors.
first modifications are in the file: baseParticleRenderer.cxx
void BaseParticleRenderer::
enable_alpha() {
_render_state = RenderState::make(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
//=== original ===
//_render_state = RenderState::make(TransparencyAttrib::make(TransparencyAttrib::M_alpha),
// ColorAttrib::make_vertex());
}
void BaseParticleRenderer::
disable_alpha() {
_render_state = RenderState::make(TransparencyAttrib::make(TransparencyAttrib::M_none));
//_render_state = RenderState::make(TransparencyAttrib::make(TransparencyAttrib::M_none),
// ColorAttrib::make_vertex());
}
part of the function: void GeomParticleRenderer::render(…) should be modified too. we could depend on number of color interpolation segments to decide if color interpolation should be used or geomnode original color attribute (vertex, flat, …)
– OR –
add a boolean (_interpolate_color) to the constructor
here are the modifications:
{
//bool _interpolate_colors = false;
PStatTimer t1(_render_collector);
BaseParticle *cur_particle;
int i, remaining_particles = ttl_particles;
pvector< PT(PandaNode) >::iterator cur_node_iter = _node_vector.begin();
// run through the particle vector
for (i = 0; i < (int)po_vector.size(); i++) {
PandaNode *cur_node;
cur_particle = (BaseParticle *) po_vector[i].p();
cur_node = *cur_node_iter;
if (cur_particle->get_alive())
{
// living particle
if (cur_node == (PandaNode *)NULL)
{
birth_particle(i);
cur_node = *cur_node_iter;
}
nassertv(cur_node != (PandaNode *)NULL);
cur_node->set_state(_render_state);
float t = cur_particle->get_parameterized_age();
Colorf c = _color_interpolation_manager->generateColor(t);
if ((_alpha_mode != PR_ALPHA_NONE))
{
float alpha_scalar;
if(_alpha_mode == PR_ALPHA_USER) {
alpha_scalar = get_user_alpha();
} else {
alpha_scalar = t;
if (_alpha_mode == PR_ALPHA_OUT)
alpha_scalar = 1.0f - alpha_scalar;
else if (_alpha_mode == PR_ALPHA_IN_OUT)
alpha_scalar = 2.0f * min(alpha_scalar, 1.0f - alpha_scalar);
alpha_scalar *= get_user_alpha();
}
c[3] *= alpha_scalar;
if(_interpolate_colors)
{
cur_node->set_attrib(ColorScaleAttrib::make(Colorf(1.0f, 1.0f, 1.0f, c[3])));
}
else
{
//=============================
// scale alpha without changing scale of the other colors
float scale = c[3];
int priority = 0;
const RenderAttrib *attrib =
cur_node->get_attrib(ColorScaleAttrib::get_class_slot());
if (attrib != (const RenderAttrib *)NULL) {
priority = max(priority,
cur_node->get_state()->get_override(ColorScaleAttrib::get_class_slot()));
const ColorScaleAttrib *csa = DCAST(ColorScaleAttrib, attrib);
// Modify the existing ColorScaleAttrib to add the indicated colorScale.
const LVecBase4f &sc = csa->get_scale();
cur_node->set_attrib(csa->set_scale(LVecBase4f(sc[0], sc[1], sc[2], scale)), priority);
} else {
// Create a new ColorScaleAttrib for this node.
cur_node->set_attrib(ColorScaleAttrib::make(LVecBase4f(1.0f, 1.0f, 1.0f, scale)), priority);
}
//========================
}
}
if(_interpolate_colors)
cur_node->set_attrib(ColorAttrib::make_flat(c), 0);
// animate scale
float current_x_scale = _initial_x_scale;
float current_y_scale = _initial_y_scale;
float current_z_scale = _initial_z_scale;
if (_animate_x_ratio || _animate_y_ratio || _animate_z_ratio) {
if (_animate_x_ratio) {
current_x_scale = (_initial_x_scale +
(t * (_final_x_scale - _initial_x_scale)));
}
if (_animate_y_ratio) {
current_y_scale = (_initial_y_scale +
(t * (_final_y_scale - _initial_y_scale)));
}
if (_animate_z_ratio) {
current_z_scale = (_initial_z_scale +
(t * (_final_z_scale - _initial_z_scale)));
}
}
cur_node->set_transform(TransformState::make_pos_quat_scale
(cur_particle->get_position(),
cur_particle->get_orientation(),
LVecBase3f(current_x_scale, current_y_scale, current_z_scale)));
// maybe get out early if possible.
remaining_particles--;
if (remaining_particles == 0)
break;
}
cur_node_iter++;
}
}