mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
NodePath::set_normal_map()
This commit is contained in:
parent
64aec0a447
commit
e5095d2c31
@ -501,7 +501,23 @@ munge_texcoord_light_vector(const CullTraverser *traverser) {
|
||||
++lvi) {
|
||||
TextureStage *stage = (*lvi);
|
||||
NodePath light = tex_gen->get_light(stage);
|
||||
nassertv(!light.is_empty());
|
||||
if (light.is_empty()) {
|
||||
// If a particular light isn't specified in the TexGenAttrib,
|
||||
// use the most important light in the current state.
|
||||
CPT(RenderAttrib) attrib = _state->get_attrib(LightAttrib::get_class_type());
|
||||
if (attrib != (RenderAttrib *)NULL) {
|
||||
CPT(LightAttrib) la = DCAST(LightAttrib, attrib);
|
||||
light = la->get_most_important_light();
|
||||
/*
|
||||
if (!light.is_empty()) {
|
||||
// Remove that light, now that we're accounting for it in
|
||||
// the normal map.
|
||||
_state->set_attrib(la->remove_on_light(light));
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (!light.is_empty()) {
|
||||
string source_name = tex_gen->get_source_name(stage);
|
||||
Light *light_obj = light.node()->as_light();
|
||||
nassertv(light_obj != (Light *)NULL);
|
||||
@ -549,6 +565,7 @@ munge_texcoord_light_vector(const CullTraverser *traverser) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CullableObject::get_flash_cpu_state
|
||||
|
@ -544,6 +544,34 @@ filter_to_max(int max_lights) const {
|
||||
return light_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::get_most_important_light
|
||||
// Access: Public
|
||||
// Description: Returns the most important light (that is, the light
|
||||
// with the highest priority) in the LightAttrib,
|
||||
// excluding any ambient lights. Returns an empty
|
||||
// NodePath if no non-ambient lights are found.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodePath LightAttrib::
|
||||
get_most_important_light() const {
|
||||
NodePath best;
|
||||
|
||||
CompareLightPriorities compare;
|
||||
|
||||
Lights::const_iterator li;
|
||||
for (li = _on_lights.begin(); li != _on_lights.end(); ++li) {
|
||||
const NodePath &np = (*li);
|
||||
nassertr(!np.is_empty() && np.node()->as_light() != (Light *)NULL, NodePath());
|
||||
if (!np.node()->is_exact_type(AmbientLight::get_class_type())) {
|
||||
if (best.is_empty() || compare(np, best)) {
|
||||
best = np;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::issue
|
||||
// Access: Public, Virtual
|
||||
|
@ -92,6 +92,7 @@ PUBLISHED:
|
||||
CPT(RenderAttrib) remove_off_light(const NodePath &light) const;
|
||||
|
||||
CPT(LightAttrib) filter_to_max(int max_lights) const;
|
||||
NodePath get_most_important_light() const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "transparencyAttrib.h"
|
||||
#include "antialiasAttrib.h"
|
||||
#include "texProjectorEffect.h"
|
||||
#include "texturePool.h"
|
||||
#include "planeNode.h"
|
||||
#include "lensNode.h"
|
||||
#include "materialPool.h"
|
||||
@ -3529,6 +3530,82 @@ project_texture(TextureStage *stage, Texture *tex, const NodePath &projector) {
|
||||
set_tex_projector(stage, NodePath(), projector);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::set_normal_map
|
||||
// Access: Published
|
||||
// Description: A convenience function to set up a normal map on this
|
||||
// geometry. This uses the single highest-priority
|
||||
// light on the object only. It also requires
|
||||
// multitexture, and consumes at least two texture
|
||||
// stages, in addition to what may already be in use.
|
||||
//
|
||||
// The normal_map parameter is the texture that contains
|
||||
// the normal map information (with a 3-d delta vector
|
||||
// encoded into the r,g,b of each texel). texcoord_name is
|
||||
// the name of the texture coordinate set that contains
|
||||
// the tangent and binormal we wish to use.
|
||||
//
|
||||
// Only one normal map may be in effect through this
|
||||
// interface at any given time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
set_normal_map(Texture *normal_map, const string &texcoord_name) {
|
||||
clear_normal_map();
|
||||
|
||||
// First, we apply the normal map itself, to the bottom layer.
|
||||
PT(TextureStage) normal_map_ts = new TextureStage("normal_map");
|
||||
normal_map_ts->set_texcoord_name(texcoord_name);
|
||||
normal_map_ts->set_sort(-20);
|
||||
normal_map_ts->set_mode(TextureStage::M_replace);
|
||||
set_texture(normal_map_ts, normal_map);
|
||||
|
||||
// Then, we apply a normalization map, to normalize, per-pixel, the
|
||||
// vector to the light.
|
||||
PT(Texture) normalization_map = TexturePool::get_normalization_cube_map(32);
|
||||
PT(TextureStage) normalization_map_ts = new TextureStage("normalization_map");
|
||||
normalization_map_ts->set_combine_rgb
|
||||
(TextureStage::CM_dot3_rgb,
|
||||
TextureStage::CS_texture, TextureStage::CO_src_color,
|
||||
TextureStage::CS_previous, TextureStage::CO_src_color);
|
||||
normalization_map_ts->set_texcoord_name("light_vector");
|
||||
normalization_map_ts->set_sort(-15);
|
||||
set_texture(normalization_map_ts, normalization_map);
|
||||
|
||||
// Finally, we enable M_light_vector texture coordinate generation.
|
||||
set_tex_gen(normalization_map_ts, TexGenAttrib::M_light_vector,
|
||||
texcoord_name, NodePath());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::clear_normal_map
|
||||
// Access: Published
|
||||
// Description: Undoes the effect of a previous call to
|
||||
// set_normal_map().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void NodePath::
|
||||
clear_normal_map() {
|
||||
// Scan through the TextureStages, and if we find any whose name
|
||||
// matches one of the stages that would have been left by
|
||||
// set_normal_map(), remove it from the state.
|
||||
|
||||
CPT(RenderAttrib) attrib =
|
||||
get_state()->get_attrib(TextureAttrib::get_class_type());
|
||||
if (attrib != (const RenderAttrib *)NULL) {
|
||||
const TextureAttrib *ta = DCAST(TextureAttrib, attrib);
|
||||
for (int i = 0; i < ta->get_num_on_stages(); i++) {
|
||||
TextureStage *stage = ta->get_on_stage(i);
|
||||
if (stage->get_name() == "normal_map") {
|
||||
clear_texture(stage);
|
||||
|
||||
} else if (stage->get_name() == "normalization_map") {
|
||||
clear_texture(stage);
|
||||
clear_tex_gen(stage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::find_texture
|
||||
// Access: Published
|
||||
|
@ -600,6 +600,9 @@ PUBLISHED:
|
||||
void project_texture(TextureStage *stage, Texture *tex, const NodePath &projector);
|
||||
INLINE void clear_project_texture(TextureStage *stage);
|
||||
|
||||
void set_normal_map(Texture *normal_map, const string &texcoord_name = string());
|
||||
void clear_normal_map();
|
||||
|
||||
Texture *find_texture(const string &name) const;
|
||||
Texture *find_texture(TextureStage *stage) const;
|
||||
TextureCollection find_all_textures() const;
|
||||
|
@ -93,21 +93,20 @@ add_stage(TextureStage *stage, TexGenAttrib::Mode mode,
|
||||
|
||||
case M_light_vector:
|
||||
{
|
||||
Light *light_obj = NULL;
|
||||
if (!light.is_empty()) {
|
||||
light_obj = light.node()->as_light();
|
||||
}
|
||||
Light *light_obj = light.node()->as_light();
|
||||
if (light_obj == (Light *)NULL) {
|
||||
ostringstream strm;
|
||||
strm << "Not a light: " << light;
|
||||
nassert_raise(strm.str());
|
||||
mode_def._light = NodePath();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
attrib->_light_vectors.insert(stage);
|
||||
attrib->_geom_rendering |= Geom::GR_texcoord_light_vector;
|
||||
attrib->_num_light_vectors++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case M_off:
|
||||
|
Loading…
x
Reference in New Issue
Block a user