add alpha-scale-via-texture

This commit is contained in:
David Rose 2006-10-10 17:58:08 +00:00
parent d7dcd2bc0b
commit 962f43800d
22 changed files with 421 additions and 63 deletions

View File

@ -201,7 +201,19 @@ ConfigVariableBool color_scale_via_lighting
"avoids the need to munge the vertex data to change each vertex's "
"color. Set this false to avoid this trickery, so that lighting "
"is only enabled when the application specifically enables "
"it."));
"it. See also alpha-scale-via-texture."));
ConfigVariableBool alpha_scale_via_texture
("alpha-scale-via-texture", false,
PRC_DESC("When this is true, Panda will try to implement "
"ColorScaleAttribs that affect alpha by "
"creating an additional Texture layer over the geometry "
"with a uniform alpha scale applied everywhere, if there "
"is at least one available Texture slot available on the "
"multitexture pipeline. Set this false to avoid this "
"trickery, so that texturing is only enabled when the "
"application specifically enables it. See also "
"color-scale-via-lighting."));
ConfigVariableInt win_size
("win-size", "640 480",

View File

@ -61,6 +61,7 @@ extern EXPCL_PANDA ConfigVariableString red_blue_stereo_colors;
extern EXPCL_PANDA ConfigVariableBool depth_offset_decals;
extern EXPCL_PANDA ConfigVariableBool auto_generate_mipmaps;
extern EXPCL_PANDA ConfigVariableBool color_scale_via_lighting;
extern EXPCL_PANDA ConfigVariableBool alpha_scale_via_texture;
extern EXPCL_PANDA ConfigVariableInt win_size;
extern EXPCL_PANDA ConfigVariableInt win_origin;

View File

@ -573,6 +573,51 @@ get_color_scale_via_lighting() const {
return _color_scale_via_lighting;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_alpha_scale_via_texture
// Access: Published
// Description: Returns true if this particular GSG can implement (or
// would prefer to implement) an alpha scale via an
// additional Texture layer, or false if we need to
// actually munge the alpha.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_alpha_scale_via_texture() const {
return _alpha_scale_via_texture;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_alpha_scale_via_texture
// Access: Published
// Description: This variant of get_alpha_scale_via_texture() answers
// the question of whether the GSG can implement an
// alpha scale via an additional Texture layer,
// considering the current TextureAttrib that will be in
// effect. This considers whether there is at least one
// additional texture slot available on the GSG.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_alpha_scale_via_texture(const TextureAttrib *tex_attrib) const {
return _alpha_scale_via_texture &&
(tex_attrib->get_num_on_stages() < get_max_texture_stages());
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_alpha_scale_texture_stage
// Access: Published, Static
// Description: Returns the TextureStage that will be used to apply
// an alpha scale, if get_alpha_scale_via_texture()
// returns true.
////////////////////////////////////////////////////////////////////
INLINE TextureStage *GraphicsStateGuardian::
get_alpha_scale_texture_stage() {
if (_alpha_scale_texture_stage == (TextureStage *)NULL) {
_alpha_scale_texture_stage = new TextureStage("alpha-scale");
_alpha_scale_texture_stage->set_sort(1000000000);
}
return _alpha_scale_texture_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_coordinate_system
// Access: Published

View File

@ -38,6 +38,7 @@
#include "drawableRegion.h"
#include "displayRegion.h"
#include "graphicsOutput.h"
#include "texturePool.h"
#include <algorithm>
#include <limits.h>
@ -68,6 +69,7 @@ PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive
PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
PT(TextureStage) GraphicsStateGuardian::_alpha_scale_texture_stage = NULL;
GraphicsStateGuardian *GraphicsStateGuardian::_global_gsg = NULL;
TypeHandle GraphicsStateGuardian::_type_handle;
@ -163,6 +165,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
// enabling lighting even without a LightAttrib).
_color_scale_via_lighting = color_scale_via_lighting;
// Similarly for applying a texture to achieve uniform alpha
// scaling.
_alpha_scale_via_texture = alpha_scale_via_texture;
_stencil_render_states = 0;
// The default is no shader support.
@ -311,6 +317,7 @@ reset() {
_color_scale_enabled = false;
_current_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
_has_texture_alpha_scale = false;
_has_material_force_color = false;
_material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
@ -1564,6 +1571,7 @@ do_issue_color_scale() {
const ColorScaleAttrib *attrib = _target._color_scale;
_color_scale_enabled = attrib->has_scale();
_current_color_scale = attrib->get_scale();
_has_texture_alpha_scale = false;
if (_color_blend_involves_color_scale) {
_state_rs = 0;
@ -1580,6 +1588,13 @@ do_issue_color_scale() {
determine_light_color_scale();
}
if (_alpha_scale_via_texture && !_has_scene_graph_color &&
attrib->has_alpha_scale()) {
_state._texture = 0;
_state._tex_matrix = 0;
_has_texture_alpha_scale = true;
}
}
////////////////////////////////////////////////////////////////////
@ -1909,6 +1924,28 @@ void GraphicsStateGuardian::
end_bind_clip_planes() {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::determine_effective_texture
// Access: Protected
// Description: Assigns _effective_texture and _effective_tex_gen
// based on the current settings of _target._texture and
// _target._color_scale.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
determine_effective_texture() {
_effective_texture = _target._texture->filter_to_max(_max_texture_stages);
_effective_tex_gen = _target._tex_gen;
if (_has_texture_alpha_scale) {
PT(TextureStage) stage = get_alpha_scale_texture_stage();
PT(Texture) texture = TexturePool::get_alpha_scale_map();
_effective_texture = DCAST(TextureAttrib, _effective_texture->add_on_stage(stage, texture));
_effective_tex_gen = DCAST(TexGenAttrib, _effective_tex_gen->add_stage
(stage, TexGenAttrib::M_constant, TexCoord3f(_current_color_scale[3], 0.0f, 0.0f)));
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::free_pointers
// Access: Protected, Virtual

View File

@ -139,6 +139,10 @@ PUBLISHED:
virtual int get_supported_geom_rendering() const;
INLINE bool get_color_scale_via_lighting() const;
INLINE bool get_alpha_scale_via_texture() const;
INLINE bool get_alpha_scale_via_texture(const TextureAttrib *tex_attrib) const;
INLINE static TextureStage *get_alpha_scale_texture_stage();
void set_coordinate_system(CoordinateSystem cs);
INLINE CoordinateSystem get_coordinate_system() const;
@ -268,6 +272,8 @@ protected:
virtual void bind_clip_plane(const NodePath &plane, int plane_id);
virtual void end_bind_clip_planes();
void determine_effective_texture();
virtual void free_pointers();
virtual void close_gsg();
void panic_deactivate();
@ -292,6 +298,13 @@ protected:
CPT(RenderState) _target_rs;
CPT(TransformState) _internal_transform;
// The current TextureAttrib is a special case; we may further
// restrict it (according to graphics cards limits) or extend it
// (according to ColorScaleAttribs in effect) beyond what is
// specifically requested in the scene graph.
CPT(TextureAttrib) _effective_texture;
CPT(TexGenAttrib) _effective_tex_gen;
// These are set by begin_draw_primitives(), and are only valid
// between begin_draw_primitives() and end_draw_primitives().
CPT(GeomMunger) _munger;
@ -329,6 +342,7 @@ protected:
bool _has_material_force_color;
Colorf _material_force_color;
LVecBase4f _light_color_scale;
bool _has_texture_alpha_scale;
bool _tex_gen_modifies_mat;
bool _tex_gen_point_sprite;
@ -383,6 +397,7 @@ protected:
int _supported_geom_rendering;
bool _color_scale_via_lighting;
bool _alpha_scale_via_texture;
int _stereo_buffer_mask;
@ -391,6 +406,8 @@ protected:
int _auto_detect_shader_model;
int _shader_model;
static PT(TextureStage) _alpha_scale_texture_stage;
public:
// Statistics
static PStatCollector _vertex_buffer_switch_pcollector;

View File

@ -73,20 +73,21 @@ StandardMunger(GraphicsStateGuardianBase *gsg, const RenderState *state,
} else if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
color_scale_attrib->has_scale()) {
_color_scale = color_scale_attrib->get_scale();
if (!_gsg->get_color_scale_via_lighting() || _color_scale[3] < 0.999f) {
// We only need to apply the color scale by directly munging the
// color if the GSG says it can't cheat this via lighting (for
// instance, by applying an ambient light). Or, since we assume
// lighting can't scale the alpha component, if the color scale
// involves alpha.
// Known bug: if there is a material on an object that would
// obscure the effect of color_scale, we scale the lighting
// anyway, thus applying the effect even if it should be
// obscured. It doesn't seem worth the effort to detect this
// contrived situation and handle it correctly.
CPT(TextureAttrib) tex_attrib = state->get_texture();
// If the GSG says it can't cheat this RGB or alpha scale, we have
// to apply the color scale directly.
if ((color_scale_attrib->has_rgb_scale() && !_gsg->get_color_scale_via_lighting()) ||
(color_scale_attrib->has_alpha_scale() && !_gsg->get_alpha_scale_via_texture(tex_attrib))) {
_munge_color_scale = true;
}
// Known bug: if there is a material on an object that would
// obscure the effect of color_scale, we scale the lighting
// anyway, thus applying the effect even if it should be obscured.
// It doesn't seem worth the effort to detect this contrived
// situation and handle it correctly.
}
}

View File

@ -5676,23 +5676,6 @@ set_state_and_transform(const RenderState *target,
_state._texture = 0;
}
if (_target._texture != _state._texture) {
do_issue_texture();
_state._texture = _target._texture;
_state._tex_gen = 0;
_state._tex_matrix = 0;
}
if (_target._material != _state._material) {
do_issue_material();
_state._material = _target._material;
}
if (_target._light != _state._light) {
do_issue_light();
_state._light = _target._light;
}
// If one of the previously-loaded TexGen modes modified the texture
// matrix, then if either state changed, we have to change both of
// them now.
@ -5704,14 +5687,29 @@ set_state_and_transform(const RenderState *target,
}
}
if (_target._texture != _state._texture ||
_target._tex_gen != _state._tex_gen) {
determine_effective_texture();
do_issue_texture();
do_issue_tex_gen();
_state._texture = _target._texture;
_state._tex_gen = _target._tex_gen;
_state._tex_matrix = 0;
}
if (_target._tex_matrix != _state._tex_matrix) {
do_issue_tex_matrix();
_state._tex_matrix = _target._tex_matrix;
}
if (_target._tex_gen != _state._tex_gen) {
do_issue_tex_gen();
_state._tex_gen = _target._tex_gen;
if (_target._material != _state._material) {
do_issue_material();
_state._material = _target._material;
}
if (_target._light != _state._light) {
do_issue_light();
_state._light = _target._light;
}
if (_target._stencil != _state._stencil) {
@ -5822,7 +5820,7 @@ do_issue_texture() {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
update_standard_texture_bindings() {
int num_stages = _target._texture->get_num_on_stages();
int num_stages = _effective_texture->get_num_on_stages();
int num_old_stages = _max_texture_stages;
if (_state._texture != (TextureAttrib *)NULL) {
num_old_stages = _state._texture->get_num_on_stages();
@ -5837,8 +5835,8 @@ update_standard_texture_bindings() {
int last_stage = -1;
int i;
for (i = 0; i < num_stages; i++) {
TextureStage *stage = _target._texture->get_on_stage(i);
Texture *texture = _target._texture->get_on_texture(stage);
TextureStage *stage = _effective_texture->get_on_stage(i);
Texture *texture = _effective_texture->get_on_texture(stage);
nassertv(texture != (Texture *)NULL);
if (i >= num_old_stages ||
@ -6057,11 +6055,11 @@ disable_standard_texture_bindings() {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
do_issue_tex_matrix() {
int num_stages = _target._texture->get_num_on_stages();
int num_stages = _effective_texture->get_num_on_stages();
nassertv(num_stages <= _max_texture_stages);
for (int i = 0; i < num_stages; i++) {
TextureStage *stage = _target._texture->get_on_stage(i);
TextureStage *stage = _effective_texture->get_on_stage(i);
_glActiveTexture(GL_TEXTURE0 + i);
GLP(MatrixMode)(GL_TEXTURE);
@ -6091,7 +6089,7 @@ void CLP(GraphicsStateGuardian)::
do_issue_tex_gen() {
bool force_normal = false;
int num_stages = _target._texture->get_num_on_stages();
int num_stages = _effective_texture->get_num_on_stages();
nassertv(num_stages <= _max_texture_stages);
// These are passed in for the four OBJECT_PLANE or EYE_PLANE
@ -6109,7 +6107,7 @@ do_issue_tex_gen() {
bool got_point_sprites = false;
for (int i = 0; i < num_stages; i++) {
TextureStage *stage = _target._texture->get_on_stage(i);
TextureStage *stage = _effective_texture->get_on_stage(i);
_glActiveTexture(GL_TEXTURE0 + i);
GLP(Disable)(GL_TEXTURE_GEN_S);
GLP(Disable)(GL_TEXTURE_GEN_T);
@ -6119,7 +6117,7 @@ do_issue_tex_gen() {
GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
}
TexGenAttrib::Mode mode = _target._tex_gen->get_mode(stage);
TexGenAttrib::Mode mode = _effective_tex_gen->get_mode(stage);
switch (mode) {
case TexGenAttrib::M_off:
case TexGenAttrib::M_light_vector:
@ -6301,6 +6299,35 @@ do_issue_tex_gen() {
}
break;
case TexGenAttrib::M_constant:
// To generate a constant UV(w) coordinate everywhere, we use
// EYE_LINEAR mode, but we construct a special matrix that
// flattens the vertex position to zero and then adds our
// desired value.
{
const TexCoord3f &v = _effective_tex_gen->get_constant_value(stage);
GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
LVecBase4f s(0.0f, 0.0f, 0.0f, v[0]);
LVecBase4f t(0.0f, 0.0f, 0.0f, v[1]);
LVecBase4f r(0.0f, 0.0f, 0.0f, v[2]);
GLP(TexGenfv)(GL_S, GL_OBJECT_PLANE, s.get_data());
GLP(TexGenfv)(GL_T, GL_OBJECT_PLANE, t.get_data());
GLP(TexGenfv)(GL_R, GL_OBJECT_PLANE, r.get_data());
GLP(TexGenfv)(GL_Q, GL_OBJECT_PLANE, q_data);
GLP(Enable)(GL_TEXTURE_GEN_S);
GLP(Enable)(GL_TEXTURE_GEN_T);
GLP(Enable)(GL_TEXTURE_GEN_R);
GLP(Enable)(GL_TEXTURE_GEN_Q);
}
break;
case TexGenAttrib::M_unused:
break;
}

View File

@ -350,6 +350,31 @@ generate_normalization_cube_map(int size) {
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::generate_alpha_scale_map
// Access: Published
// Description: Generates a special 256x1 1-d texture that can be
// used to apply an arbitrary alpha scale to objects by
// judicious use of texture matrix. The texture is a
// gradient, with an alpha of 0 on the left (U = 0), and
// 255 on the right (U = 1).
////////////////////////////////////////////////////////////////////
void Texture::
generate_alpha_scale_map() {
setup_1d_texture(256, T_unsigned_byte, F_alpha);
set_wrap_u(WM_clamp);
set_minfilter(FT_nearest);
set_magfilter(FT_nearest);
PTA_uchar image = make_ram_image();
_keep_ram_image = true;
unsigned char *p = image;
for (int xi = 0; xi < 256; ++xi) {
*p++ = xi;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::estimate_texture_memory
// Access: Published

View File

@ -199,6 +199,7 @@ PUBLISHED:
ComponentType component_type, Format format);
void generate_normalization_cube_map(int size);
void generate_alpha_scale_map();
INLINE bool read(const Filename &fullpath);
INLINE bool read(const Filename &fullpath, const Filename &alpha_fullpath,

View File

@ -143,6 +143,22 @@ get_normalization_cube_map(int size) {
return get_global_ptr()->ns_get_normalization_cube_map(size);
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::get_alpha_scale_map
// Access: Published, Static
// Description: Returns a standard Texture object that has been
// created with Texture::generate_alpha_scale_map().
//
// This Texture object is used internally by Panda to
// apply an alpha scale to an object (instead of munging
// its vertices) when gsg->get_alpha_scale_via_texture()
// returns true.
////////////////////////////////////////////////////////////////////
INLINE Texture *TexturePool::
get_alpha_scale_map() {
return get_global_ptr()->ns_get_alpha_scale_map();
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::add_texture
// Access: Published, Static

View File

@ -657,6 +657,23 @@ ns_get_normalization_cube_map(int size) {
return _normalization_cube_map;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::ns_get_alpha_scale_map
// Access: Private
// Description: The nonstatic implementation of get_alpha_scale_map().
////////////////////////////////////////////////////////////////////
Texture *TexturePool::
ns_get_alpha_scale_map() {
MutexHolder holder(_lock);
if (_alpha_scale_map == (Texture *)NULL) {
_alpha_scale_map = new Texture("alpha_scale_map");
_alpha_scale_map->generate_alpha_scale_map();
}
return _alpha_scale_map;
}
////////////////////////////////////////////////////////////////////
// Function: TexturePool::ns_add_texture
// Access: Private

View File

@ -57,6 +57,7 @@ PUBLISHED:
bool read_mipmaps = false);
INLINE static Texture *get_normalization_cube_map(int size);
INLINE static Texture *get_alpha_scale_map();
INLINE static void add_texture(Texture *texture);
INLINE static void release_texture(Texture *texture);
@ -101,6 +102,7 @@ private:
Texture *ns_load_cube_map(const Filename &filename_pattern,
bool read_mipmaps);
Texture *ns_get_normalization_cube_map(int size);
Texture *ns_get_alpha_scale_map();
void ns_add_texture(Texture *texture);
void ns_release_texture(Texture *texture);
@ -128,6 +130,7 @@ private:
string _fake_texture_image;
PT(Texture) _normalization_cube_map;
PT(Texture) _alpha_scale_map;
typedef pmap<string, MakeTextureFunc *> TypeRegistry;
TypeRegistry _type_registry;

View File

@ -17,21 +17,6 @@
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::Constructor
// Access: Protected
// Description: Use ColorScaleAttrib::make() to construct a new
// ColorScaleAttrib object.
////////////////////////////////////////////////////////////////////
INLINE ColorScaleAttrib::
ColorScaleAttrib(bool off, const LVecBase4f &scale) :
_off(off),
_scale(scale)
{
quantize_scale();
_has_scale = !_scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::Copy Constructor
// Access: Protected
@ -42,6 +27,8 @@ INLINE ColorScaleAttrib::
ColorScaleAttrib(const ColorScaleAttrib &copy) :
_off(copy._off),
_has_scale(copy._has_scale),
_has_rgb_scale(copy._has_rgb_scale),
_has_alpha_scale(copy._has_alpha_scale),
_scale(copy._scale)
{
}
@ -84,6 +71,30 @@ has_scale() const {
return _has_scale;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::has_rgb_scale
// Access: Published
// Description: Returns true if the ColorScaleAttrib has a
// non-identity scale in the RGB components (ignoring
// alpha), or false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool ColorScaleAttrib::
has_rgb_scale() const {
return _has_rgb_scale;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::has_alpha_scale
// Access: Published
// Description: Returns true if the ColorScaleAttrib has a
// non-identity scale in the alpha component (ignoring
// RGB), or false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool ColorScaleAttrib::
has_alpha_scale() const {
return _has_alpha_scale;
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::get_scale
// Access: Published

View File

@ -29,6 +29,23 @@
TypeHandle ColorScaleAttrib::_type_handle;
CPT(RenderAttrib) ColorScaleAttrib::_identity_attrib;
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::Constructor
// Access: Protected
// Description: Use ColorScaleAttrib::make() to construct a new
// ColorScaleAttrib object.
////////////////////////////////////////////////////////////////////
ColorScaleAttrib::
ColorScaleAttrib(bool off, const LVecBase4f &scale) :
_off(off),
_scale(scale)
{
quantize_scale();
_has_scale = !_scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
_has_rgb_scale = !LVecBase3f(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f));
_has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f);
}
////////////////////////////////////////////////////////////////////
// Function: ColorScaleAttrib::make_identity
// Access: Published, Static
@ -85,6 +102,8 @@ set_scale(const LVecBase4f &scale) const {
attrib->_scale = scale;
attrib->quantize_scale();
attrib->_has_scale = !scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
attrib->_has_rgb_scale = !LVecBase3f(scale[0], scale[1], scale[2]).almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f));
attrib->_has_alpha_scale = !IS_NEARLY_EQUAL(scale[3], 1.0f);
return return_new(attrib);
}
@ -346,4 +365,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_scale.read_datagram(scan);
quantize_scale();
_has_scale = !_scale.almost_equal(LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f));
_has_rgb_scale = !LVecBase3f(_scale[0], _scale[1], _scale[2]).almost_equal(LVecBase3f(1.0f, 1.0f, 1.0f));
_has_alpha_scale = !IS_NEARLY_EQUAL(_scale[3], 1.0f);
}

View File

@ -33,7 +33,7 @@ class FactoryParams;
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ColorScaleAttrib : public RenderAttrib {
protected:
INLINE ColorScaleAttrib(bool off, const LVecBase4f &scale);
ColorScaleAttrib(bool off, const LVecBase4f &scale);
INLINE ColorScaleAttrib(const ColorScaleAttrib &copy);
PUBLISHED:
@ -44,6 +44,8 @@ PUBLISHED:
INLINE bool is_off() const;
INLINE bool is_identity() const;
INLINE bool has_scale() const;
INLINE bool has_rgb_scale() const;
INLINE bool has_alpha_scale() const;
INLINE const LVecBase4f &get_scale() const;
CPT(RenderAttrib) set_scale(const LVecBase4f &scale) const;
@ -64,6 +66,8 @@ private:
private:
bool _off;
bool _has_scale;
bool _has_rgb_scale;
bool _has_alpha_scale;
LVecBase4f _scale;
static CPT(RenderAttrib) _identity_attrib;

View File

@ -3576,6 +3576,36 @@ set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
node()->set_attrib(tga->add_stage(stage, mode, source_name, light), priority);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_tex_gen
// Access: Published
// Description: Enables automatic texture coordinate generation for
// the indicated texture stage. This version of this
// method is useful when setting M_constant, which
// requires a constant texture coordinate value.
////////////////////////////////////////////////////////////////////
void NodePath::
set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const TexCoord3f &constant_value, int priority) {
nassertv_always(!is_empty());
const RenderAttrib *attrib =
node()->get_attrib(TexGenAttrib::get_class_type());
CPT(TexGenAttrib) tga;
if (attrib != (const RenderAttrib *)NULL) {
priority = max(priority,
node()->get_state()->get_override(TextureAttrib::get_class_type()));
tga = DCAST(TexGenAttrib, attrib);
} else {
tga = DCAST(TexGenAttrib, TexGenAttrib::make());
}
node()->set_attrib(tga->add_stage(stage, mode, constant_value), priority);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::clear_tex_gen
// Access: Published

View File

@ -636,6 +636,9 @@ PUBLISHED:
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const string &source_name, const NodePath &light,
int priority = 0);
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const TexCoord3f &constant_value,
int priority = 0);
void clear_tex_gen();
void clear_tex_gen(TextureStage *stage);
bool has_tex_gen(TextureStage *stage) const;

View File

@ -164,6 +164,11 @@ PUBLISHED:
// tangent and binormal for the particular named texture
// coordinate set.
M_light_vector,
// M_constant generates the same fixed texture coordinates at each
// vertex. Not terribly useful, of course, except for certain
// special effects involving moving a flat color over an object.
M_constant,
};
protected:

View File

@ -37,7 +37,7 @@ public:
CPT(RenderState) munge_state(const RenderState *state);
protected:
CPT(RenderState) munge_state_impl(const RenderState *state);
virtual CPT(RenderState) munge_state_impl(const RenderState *state);
typedef pmap< WCPT(RenderState), WCPT(RenderState) > StateMap;
StateMap _state_map;

View File

@ -117,6 +117,11 @@ compare_to(const TexGenAttrib::ModeDef &other) const {
if (compare != 0) {
return compare;
}
return strcmp(_source_name.c_str(), other._source_name.c_str());
compare = strcmp(_source_name.c_str(), other._source_name.c_str());
if (compare != 0) {
return compare;
}
compare = _constant_value.compare_to(other._constant_value);
return compare;
}

View File

@ -62,9 +62,8 @@ make() {
// indicated stage.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TexGenAttrib::
make(TextureStage *stage, TexGenAttrib::Mode mode,
const string &source_name, const NodePath &light) {
return DCAST(TexGenAttrib, make())->add_stage(stage, mode, source_name, light);
make(TextureStage *stage, TexGenAttrib::Mode mode) {
return DCAST(TexGenAttrib, make())->add_stage(stage, mode);
}
////////////////////////////////////////////////////////////////////
@ -76,8 +75,35 @@ make(TextureStage *stage, TexGenAttrib::Mode mode,
// replaced.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TexGenAttrib::
add_stage(TextureStage *stage, TexGenAttrib::Mode mode) const {
nassertr(mode != M_light_vector && mode != M_constant, this);
CPT(RenderAttrib) removed = remove_stage(stage);
TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
ModeDef &mode_def = attrib->_stages[stage];
mode_def._mode = mode;
attrib->record_stage(stage, mode_def);
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::add_stage
// Access: Published, Static
// Description: Returns a new TexGenAttrib just like this one,
// with the indicated generation mode for the given
// stage. If this stage already exists, its mode is
// replaced.
//
// This variant also accepts source_name and light,
// which are only meaningful if mode is M_light_vector.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TexGenAttrib::
add_stage(TextureStage *stage, TexGenAttrib::Mode mode,
const string &source_name, const NodePath &light) const {
nassertr(mode == M_light_vector, this);
CPT(RenderAttrib) removed = remove_stage(stage);
TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
@ -90,6 +116,33 @@ add_stage(TextureStage *stage, TexGenAttrib::Mode mode,
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::add_stage
// Access: Published, Static
// Description: Returns a new TexGenAttrib just like this one,
// with the indicated generation mode for the given
// stage. If this stage already exists, its mode is
// replaced.
//
// This variant also accepts constant_value, which is
// only meaningful if mode is M_constant.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TexGenAttrib::
add_stage(TextureStage *stage, TexGenAttrib::Mode mode,
const TexCoord3f &constant_value) const {
nassertr(mode == M_constant, this);
CPT(RenderAttrib) removed = remove_stage(stage);
TexGenAttrib *attrib = new TexGenAttrib(*DCAST(TexGenAttrib, removed));
ModeDef &mode_def = attrib->_stages[stage];
mode_def._mode = mode;
mode_def._constant_value = constant_value;
attrib->record_stage(stage, mode_def);
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::remove_stage
// Access: Published, Static
@ -200,6 +253,22 @@ get_light(TextureStage *stage) const {
return NodePath();
}
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::get_constant_value
// Access: Published
// Description: Returns the constant value associated with the named
// texture stage. This is only meaningful if the mode
// is M_constant.
////////////////////////////////////////////////////////////////////
const TexCoord3f &TexGenAttrib::
get_constant_value(TextureStage *stage) const {
Stages::const_iterator mi = _stages.find(stage);
if (mi != _stages.end()) {
return (*mi).second._constant_value;
}
return TexCoord3f::zero();
}
////////////////////////////////////////////////////////////////////
// Function: TexGenAttrib::output
// Access: Public, Virtual
@ -253,6 +322,10 @@ output(ostream &out) const {
<< mode_def._light;
break;
case M_constant:
out << "constant: " << mode_def._constant_value;
break;
case M_unused:
break;
}

View File

@ -54,9 +54,11 @@ public:
PUBLISHED:
static CPT(RenderAttrib) make();
static CPT(RenderAttrib) make(TextureStage *stage, Mode mode, const string &source_name = string(), const NodePath &light = NodePath());
static CPT(RenderAttrib) make(TextureStage *stage, Mode mode);
CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode, const string &source_name = string(), const NodePath &light = NodePath()) const;
CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode) const;
CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode, const string &source_name, const NodePath &light) const;
CPT(RenderAttrib) add_stage(TextureStage *stage, Mode mode, const TexCoord3f &constant_value) const;
CPT(RenderAttrib) remove_stage(TextureStage *stage) const;
bool is_empty() const;
@ -64,6 +66,7 @@ PUBLISHED:
Mode get_mode(TextureStage *stage) const;
string get_source_name(TextureStage *stage) const;
NodePath get_light(TextureStage *stage) const;
const TexCoord3f &get_constant_value(TextureStage *stage) const;
INLINE int get_geom_rendering(int geom_rendering) const;
@ -94,6 +97,7 @@ private:
Mode _mode;
string _source_name;
NodePath _light;
TexCoord3f _constant_value;
};
typedef pmap<PT(TextureStage), ModeDef> Stages;
Stages _stages;