add set_priority() to Light, PlaneNode
This commit is contained in:
parent
4589c7da34
commit
512acd4adf
|
|
@ -233,6 +233,38 @@ get_max_cube_map_dimension() const {
|
|||
return _max_cube_map_dimension;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_lights
|
||||
// Access: Published
|
||||
// Description: Returns the maximum number of simultaneous lights
|
||||
// that may be rendered on geometry, or -1 if there is
|
||||
// no particular limit.
|
||||
//
|
||||
// The value returned may not be meaningful until after
|
||||
// the graphics context has been fully created (e.g. the
|
||||
// window has been opened).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GraphicsStateGuardian::
|
||||
get_max_lights() const {
|
||||
return _max_lights;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_clip_planes
|
||||
// Access: Published
|
||||
// Description: Returns the maximum number of simultaneous clip planes
|
||||
// that may be applied to geometry, or -1 if there is
|
||||
// no particular limit.
|
||||
//
|
||||
// The value returned may not be meaningful until after
|
||||
// the graphics context has been fully created (e.g. the
|
||||
// window has been opened).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GraphicsStateGuardian::
|
||||
get_max_clip_planes() const {
|
||||
return _max_clip_planes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_vertex_transforms
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
|||
_max_3d_texture_dimension = 0;
|
||||
_max_cube_map_dimension = 0;
|
||||
|
||||
// Assume no limits on number of lights or clip planes.
|
||||
_max_lights = -1;
|
||||
_max_clip_planes = -1;
|
||||
|
||||
// Assume no vertex blending capability.
|
||||
_max_vertex_transforms = 0;
|
||||
_max_vertex_transform_indices = 0;
|
||||
|
|
@ -1163,23 +1167,25 @@ issue_texture(const TextureAttrib *attrib) {
|
|||
// Function: GraphicsStateGuardian::issue_clip_plane
|
||||
// Access: Public, Virtual
|
||||
// Description: This is fundametically similar to issue_light(), with
|
||||
// calls to slot_new_clip_plane(), apply_clip_plane(),
|
||||
// and enable_clip_planes(), as appropriate.
|
||||
// calls to apply_clip_plane() and enable_clip_planes(),
|
||||
// as appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
||||
int i;
|
||||
int max_planes = (int)_clip_plane_info.size();
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
int cur_max_planes = (int)_clip_plane_info.size();
|
||||
for (i = 0; i < cur_max_planes; i++) {
|
||||
_clip_plane_info[i]._next_enabled = false;
|
||||
}
|
||||
|
||||
CPT(ClipPlaneAttrib) new_attrib = attrib->filter_to_max(_max_clip_planes);
|
||||
|
||||
bool any_bound = false;
|
||||
|
||||
int num_enabled = 0;
|
||||
int num_on_planes = attrib->get_num_on_planes();
|
||||
int num_on_planes = new_attrib->get_num_on_planes();
|
||||
for (int li = 0; li < num_on_planes; li++) {
|
||||
NodePath plane = attrib->get_on_plane(li);
|
||||
NodePath plane = new_attrib->get_on_plane(li);
|
||||
nassertv(!plane.is_empty() && plane.node()->is_of_type(PlaneNode::get_class_type()));
|
||||
|
||||
num_enabled++;
|
||||
|
|
@ -1191,7 +1197,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
|||
|
||||
// Check to see if this plane has already been bound to an id
|
||||
int cur_plane_id = -1;
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
for (i = 0; i < cur_max_planes; i++) {
|
||||
if (_clip_plane_info[i]._plane == plane) {
|
||||
// Plane has already been bound to an id, we only need to
|
||||
// enable the plane, not reapply it.
|
||||
|
|
@ -1205,7 +1211,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
|||
|
||||
// See if there are any unbound plane ids
|
||||
if (cur_plane_id == -1) {
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
for (i = 0; i < cur_max_planes; i++) {
|
||||
if (_clip_plane_info[i]._plane.is_empty()) {
|
||||
_clip_plane_info[i]._plane = plane;
|
||||
cur_plane_id = i;
|
||||
|
|
@ -1217,8 +1223,8 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
|||
// If there were no unbound plane ids, see if we can replace
|
||||
// a currently unused but previously bound id
|
||||
if (cur_plane_id == -1) {
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
if (!attrib->has_on_plane(_clip_plane_info[i]._plane)) {
|
||||
for (i = 0; i < cur_max_planes; i++) {
|
||||
if (!new_attrib->has_on_plane(_clip_plane_info[i]._plane)) {
|
||||
_clip_plane_info[i]._plane = plane;
|
||||
cur_plane_id = i;
|
||||
break;
|
||||
|
|
@ -1228,11 +1234,11 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
|||
|
||||
// If we *still* don't have a plane id, slot a new one.
|
||||
if (cur_plane_id == -1) {
|
||||
if (slot_new_clip_plane(max_planes)) {
|
||||
cur_plane_id = max_planes;
|
||||
if (_max_clip_planes < 0 || cur_max_planes < _max_clip_planes) {
|
||||
cur_plane_id = cur_max_planes;
|
||||
_clip_plane_info.push_back(ClipPlaneInfo());
|
||||
max_planes++;
|
||||
nassertv(max_planes == (int)_clip_plane_info.size());
|
||||
cur_max_planes++;
|
||||
nassertv(cur_max_planes == (int)_clip_plane_info.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1257,7 +1263,7 @@ issue_clip_plane(const ClipPlaneAttrib *attrib) {
|
|||
}
|
||||
|
||||
// Disable all unused planes
|
||||
for (i = 0; i < max_planes; i++) {
|
||||
for (i = 0; i < cur_max_planes; i++) {
|
||||
if (!_clip_plane_info[i]._next_enabled) {
|
||||
enable_clip_plane(i, false);
|
||||
_clip_plane_info[i]._enabled = false;
|
||||
|
|
@ -1321,8 +1327,8 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
|||
// light associated with the same id where possible, but
|
||||
// reusing id's when necessary. When it is no longer
|
||||
// possible to reuse existing id's (e.g. all id's are in
|
||||
// use), slot_new_light() is called to prepare the next
|
||||
// sequential light id.
|
||||
// use), the next sequential id is assigned (if
|
||||
// available).
|
||||
//
|
||||
// It will call apply_light() each time a light is
|
||||
// assigned to a particular id for the first time in a
|
||||
|
|
@ -1337,8 +1343,8 @@ do_issue_light() {
|
|||
// light list
|
||||
Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
int i;
|
||||
int max_lights = (int)_light_info.size();
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
int cur_max_lights = (int)_light_info.size();
|
||||
for (i = 0; i < cur_max_lights; i++) {
|
||||
_light_info[i]._next_enabled = false;
|
||||
}
|
||||
|
||||
|
|
@ -1346,9 +1352,11 @@ do_issue_light() {
|
|||
|
||||
int num_enabled = 0;
|
||||
if (_pending_light != (LightAttrib *)NULL) {
|
||||
int num_on_lights = _pending_light->get_num_on_lights();
|
||||
CPT(LightAttrib) new_light = _pending_light->filter_to_max(_max_lights);
|
||||
|
||||
int num_on_lights = new_light->get_num_on_lights();
|
||||
for (int li = 0; li < num_on_lights; li++) {
|
||||
NodePath light = _pending_light->get_on_light(li);
|
||||
NodePath light = new_light->get_on_light(li);
|
||||
nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL);
|
||||
Light *light_obj = light.node()->as_light();
|
||||
|
||||
|
|
@ -1367,7 +1375,7 @@ do_issue_light() {
|
|||
} else {
|
||||
// Check to see if this light has already been bound to an id
|
||||
int cur_light_id = -1;
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
for (i = 0; i < cur_max_lights; i++) {
|
||||
if (_light_info[i]._light == light) {
|
||||
// Light has already been bound to an id; reuse the same id.
|
||||
cur_light_id = -2;
|
||||
|
|
@ -1386,7 +1394,7 @@ do_issue_light() {
|
|||
|
||||
// See if there are any unbound light ids
|
||||
if (cur_light_id == -1) {
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
for (i = 0; i < cur_max_lights; i++) {
|
||||
if (_light_info[i]._light.is_empty()) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
|
|
@ -1398,8 +1406,8 @@ do_issue_light() {
|
|||
// If there were no unbound light ids, see if we can replace
|
||||
// a currently unused but previously bound id
|
||||
if (cur_light_id == -1) {
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
if (!_pending_light->has_on_light(_light_info[i]._light)) {
|
||||
for (i = 0; i < cur_max_lights; i++) {
|
||||
if (!new_light->has_on_light(_light_info[i]._light)) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
break;
|
||||
|
|
@ -1409,11 +1417,11 @@ do_issue_light() {
|
|||
|
||||
// If we *still* don't have a light id, slot a new one.
|
||||
if (cur_light_id == -1) {
|
||||
if (slot_new_light(max_lights)) {
|
||||
cur_light_id = max_lights;
|
||||
if (_max_lights < 0 || cur_max_lights < _max_lights) {
|
||||
cur_light_id = cur_max_lights;
|
||||
_light_info.push_back(LightInfo());
|
||||
max_lights++;
|
||||
nassertv(max_lights == (int)_light_info.size());
|
||||
cur_max_lights++;
|
||||
nassertv(cur_max_lights == (int)_light_info.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1440,7 +1448,7 @@ do_issue_light() {
|
|||
}
|
||||
|
||||
// Disable all unused lights
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
for (i = 0; i < cur_max_lights; i++) {
|
||||
if (!_light_info[i]._next_enabled) {
|
||||
enable_light(i, false);
|
||||
_light_info[i]._enabled = false;
|
||||
|
|
@ -1491,24 +1499,6 @@ void GraphicsStateGuardian::
|
|||
do_issue_texture() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular light id will be used for the first time.
|
||||
// It is intended to allow the derived class to reserve
|
||||
// any additional resources, if required, for the new
|
||||
// light; and also to indicate whether the hardware
|
||||
// supports this many simultaneous lights.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// light is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
slot_new_light(int light_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::enable_lighting
|
||||
// Access: Protected, Virtual
|
||||
|
|
@ -1573,25 +1563,6 @@ void GraphicsStateGuardian::
|
|||
end_bind_lights() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::slot_new_clip_plane
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular clip plane id will be used for the first
|
||||
// time. It is intended to allow the derived class to
|
||||
// reserve any additional resources, if required, for
|
||||
// the new clip plane; and also to indicate whether the
|
||||
// hardware supports this many simultaneous clipping
|
||||
// planes.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// plane is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
slot_new_clip_plane(int plane_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::enable_clip_planes
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ PUBLISHED:
|
|||
INLINE int get_max_3d_texture_dimension() const;
|
||||
INLINE int get_max_cube_map_dimension() const;
|
||||
|
||||
INLINE int get_max_lights() const;
|
||||
INLINE int get_max_clip_planes() const;
|
||||
|
||||
INLINE int get_max_vertex_transforms() const;
|
||||
INLINE int get_max_vertex_transform_indices() const;
|
||||
|
||||
|
|
@ -225,7 +228,6 @@ protected:
|
|||
virtual void do_issue_texture();
|
||||
|
||||
INLINE NodePath get_light(int light_id) const;
|
||||
virtual bool slot_new_light(int light_id);
|
||||
virtual void enable_lighting(bool enable);
|
||||
virtual void set_ambient_light(const Colorf &color);
|
||||
virtual void enable_light(int light_id, bool enable);
|
||||
|
|
@ -233,7 +235,6 @@ protected:
|
|||
virtual void end_bind_lights();
|
||||
|
||||
INLINE NodePath get_clip_plane(int plane_id) const;
|
||||
virtual bool slot_new_clip_plane(int plane_id);
|
||||
virtual void enable_clip_planes(bool enable);
|
||||
virtual void enable_clip_plane(int plane_id, bool enable);
|
||||
virtual void begin_bind_clip_planes();
|
||||
|
|
@ -361,6 +362,9 @@ protected:
|
|||
int _max_3d_texture_dimension;
|
||||
int _max_cube_map_dimension;
|
||||
|
||||
int _max_lights;
|
||||
int _max_clip_planes;
|
||||
|
||||
int _max_vertex_transforms;
|
||||
int _max_vertex_transform_indices;
|
||||
|
||||
|
|
|
|||
|
|
@ -1509,8 +1509,8 @@ reset() {
|
|||
}
|
||||
|
||||
_max_texture_stages = d3d_caps.MaxSimultaneousTextures;
|
||||
_max_lights = d3d_caps.MaxActiveLights;
|
||||
_max_clip_planes = d3d_caps.MaxUserClipPlanes;
|
||||
_max_lights = (int)d3d_caps.MaxActiveLights;
|
||||
_max_clip_planes = (int)d3d_caps.MaxUserClipPlanes;
|
||||
_max_vertex_transforms = d3d_caps.MaxVertexBlendMatrices;
|
||||
_max_vertex_transform_indices = d3d_caps.MaxVertexBlendMatrixIndex;
|
||||
|
||||
|
|
@ -2293,24 +2293,6 @@ do_issue_texture() {
|
|||
_current_texture = new_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular light id will be used for the first time.
|
||||
// It is intended to allow the derived class to reserve
|
||||
// any additional resources, if required, for the new
|
||||
// light; and also to indicate whether the hardware
|
||||
// supports this many simultaneous lights.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// light is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian8::
|
||||
slot_new_light(int light_id) {
|
||||
return ((unsigned int)light_id < _max_lights);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::enable_lighting
|
||||
// Access: Protected, Virtual
|
||||
|
|
@ -2361,25 +2343,6 @@ enable_light(int light_id, bool enable) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::slot_new_clip_plane
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular clip plane id will be used for the first
|
||||
// time. It is intended to allow the derived class to
|
||||
// reserve any additional resources, if required, for
|
||||
// the new clip plane; and also to indicate whether the
|
||||
// hardware supports this many simultaneous clipping
|
||||
// planes.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// plane is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian8::
|
||||
slot_new_clip_plane(int plane_id) {
|
||||
return ((unsigned int)plane_id < _max_clip_planes);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::enable_clip_plane
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -121,12 +121,10 @@ protected:
|
|||
virtual void do_issue_material();
|
||||
virtual void do_issue_texture();
|
||||
|
||||
virtual bool slot_new_light(int light_id);
|
||||
virtual void enable_lighting(bool enable);
|
||||
virtual void set_ambient_light(const Colorf &color);
|
||||
virtual void enable_light(int light_id, bool enable);
|
||||
|
||||
virtual bool slot_new_clip_plane(int plane_id);
|
||||
virtual void enable_clip_plane(int plane_id, bool enable);
|
||||
virtual void bind_clip_plane(const NodePath &plane, int plane_id);
|
||||
|
||||
|
|
@ -223,9 +221,6 @@ protected:
|
|||
D3DBLEND _blend_source_func;
|
||||
D3DBLEND _blend_dest_func;
|
||||
|
||||
unsigned int _max_lights;
|
||||
unsigned int _max_clip_planes;
|
||||
|
||||
bool _color_material_enabled;
|
||||
bool _texturing_enabled;
|
||||
bool _dither_enabled;
|
||||
|
|
|
|||
|
|
@ -3795,24 +3795,6 @@ get_light_color(Light *light) const {
|
|||
return c.get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular light id will be used for the first time.
|
||||
// It is intended to allow the derived class to reserve
|
||||
// any additional resources, if required, for the new
|
||||
// light; and also to indicate whether the hardware
|
||||
// supports this many simultaneous lights.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// light is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
slot_new_light(int light_id) {
|
||||
return (light_id < _max_lights);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::enable_lighting
|
||||
// Access: Protected, Virtual
|
||||
|
|
@ -3908,25 +3890,6 @@ end_bind_lights() {
|
|||
GLP(PopMatrix)();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::slot_new_clip_plane
|
||||
// Access: Protected, Virtual
|
||||
// Description: This will be called by the base class before a
|
||||
// particular clip plane id will be used for the first
|
||||
// time. It is intended to allow the derived class to
|
||||
// reserve any additional resources, if required, for
|
||||
// the new clip plane; and also to indicate whether the
|
||||
// hardware supports this many simultaneous clipping
|
||||
// planes.
|
||||
//
|
||||
// The return value should be true if the additional
|
||||
// plane is supported, or false if it is not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
slot_new_clip_plane(int plane_id) {
|
||||
return (plane_id < _max_clip_planes);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::enable_clip_plane
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -170,14 +170,12 @@ protected:
|
|||
bool is_at_least_version(int major_version, int minor_version, int release_version = 0) const;
|
||||
virtual void *get_extension_func(const char *prefix, const char *name);
|
||||
|
||||
virtual bool slot_new_light(int light_id);
|
||||
virtual void enable_lighting(bool enable);
|
||||
virtual void set_ambient_light(const Colorf &color);
|
||||
virtual void enable_light(int light_id, bool enable);
|
||||
virtual void begin_bind_lights();
|
||||
virtual void end_bind_lights();
|
||||
|
||||
virtual bool slot_new_clip_plane(int plane_id);
|
||||
virtual void enable_clip_plane(int plane_id, bool enable);
|
||||
virtual void begin_bind_clip_planes();
|
||||
virtual void bind_clip_plane(const NodePath &plane, int plane_id);
|
||||
|
|
@ -284,9 +282,6 @@ protected:
|
|||
bool _dithering_enabled;
|
||||
bool _texgen_forced_normal;
|
||||
|
||||
int _max_lights;
|
||||
int _max_clip_planes;
|
||||
|
||||
LMatrix4f _projection_mat;
|
||||
int _viewport_width;
|
||||
int _viewport_height;
|
||||
|
|
|
|||
|
|
@ -617,7 +617,7 @@ get_default() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureStage::get_sort_seq
|
||||
// Access: Published, Static
|
||||
// Access: Public, Static
|
||||
// Description: Returns a global sequence number that is incremented
|
||||
// any time any TextureStage in the world changes sort
|
||||
// or priority. This is used by TextureAttrib to
|
||||
|
|
|
|||
|
|
@ -158,6 +158,8 @@ PUBLISHED:
|
|||
void output(ostream &out) const;
|
||||
|
||||
INLINE static TextureStage *get_default();
|
||||
|
||||
public:
|
||||
INLINE static UpdateSeq get_sort_seq();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -48,6 +48,21 @@ AmbientLight(const AmbientLight ©) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AmbientLight::get_class_priority
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the relative priority associated with all
|
||||
// lights of this class. This priority is used to order
|
||||
// lights whose instance priority (get_priority()) is
|
||||
// the same--the idea is that other things being equal,
|
||||
// AmbientLights (for instance) are less important than
|
||||
// DirectionalLights.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int AmbientLight::
|
||||
get_class_priority() const {
|
||||
return (int)CP_ambient_priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: AmbientLight::make_copy
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ protected:
|
|||
public:
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
PUBLISHED:
|
||||
virtual int get_class_priority() const;
|
||||
|
||||
public:
|
||||
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
|
||||
|
|
|
|||
|
|
@ -133,3 +133,20 @@ INLINE bool ClipPlaneAttrib::
|
|||
is_identity() const {
|
||||
return _on_planes.empty() && _off_planes.empty() && !_off_all_planes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::check_filtered
|
||||
// Access: Private
|
||||
// Description: Confirms whether the _filtered table is still valid.
|
||||
// It may become invalid if someone calls
|
||||
// PlaneNode::set_priority().
|
||||
//
|
||||
// If the table is invalid, transparently empties it
|
||||
// before returning.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ClipPlaneAttrib::
|
||||
check_filtered() const {
|
||||
if (_sort_seq != PlaneNode::get_sort_seq()) {
|
||||
((ClipPlaneAttrib *)this)->sort_on_planes();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,20 @@ CPT(RenderAttrib) ClipPlaneAttrib::_empty_attrib;
|
|||
CPT(RenderAttrib) ClipPlaneAttrib::_all_off_attrib;
|
||||
TypeHandle ClipPlaneAttrib::_type_handle;
|
||||
|
||||
// This STL Function object is used in filter_to_max(), below, to sort
|
||||
// a list of PlaneNodes in reverse order by priority.
|
||||
class ComparePlaneNodePriorities {
|
||||
public:
|
||||
bool operator ()(const NodePath &a, const NodePath &b) const {
|
||||
nassertr(!a.is_empty() && !b.is_empty(), a < b);
|
||||
PlaneNode *pa = DCAST(PlaneNode, a.node());
|
||||
PlaneNode *pb = DCAST(PlaneNode, b.node());
|
||||
nassertr(pa != (PlaneNode *)NULL && pb != (PlaneNode *)NULL, a < b);
|
||||
|
||||
return pa->get_priority() > pb->get_priority();
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::make
|
||||
// Access: Published, Static
|
||||
|
|
@ -447,6 +461,61 @@ remove_off_plane(const NodePath &plane) const {
|
|||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::filter_to_max
|
||||
// Access: Public
|
||||
// Description: Returns a new ClipPlaneAttrib, very much like this one,
|
||||
// but with the number of on_planes reduced to be no
|
||||
// more than max_clip_planes. The number of off_planes in
|
||||
// the new ClipPlaneAttrib is undefined.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(ClipPlaneAttrib) ClipPlaneAttrib::
|
||||
filter_to_max(int max_clip_planes) const {
|
||||
if (max_clip_planes < 0 || (int)_on_planes.size() <= max_clip_planes) {
|
||||
// Trivial case: this ClipPlaneAttrib qualifies.
|
||||
return this;
|
||||
}
|
||||
|
||||
// Since check_filtered() will clear the _filtered list if we are out
|
||||
// of date, we should call it first.
|
||||
check_filtered();
|
||||
|
||||
Filtered::const_iterator fi;
|
||||
fi = _filtered.find(max_clip_planes);
|
||||
if (fi != _filtered.end()) {
|
||||
// Easy case: we have already computed this for this particular
|
||||
// ClipPlaneAttrib.
|
||||
return (*fi).second;
|
||||
}
|
||||
|
||||
// Harder case: we have to compute it now. We must choose the n
|
||||
// planeNodes with the highest priority in our list of planeNodes.
|
||||
Planes priority_planes = _on_planes;
|
||||
|
||||
// This sort function uses the STL function object defined above.
|
||||
sort(priority_planes.begin(), priority_planes.end(),
|
||||
ComparePlaneNodePriorities());
|
||||
|
||||
// Now lop off all of the planeNodes after the first max_clip_planes.
|
||||
priority_planes.erase(priority_planes.begin() + max_clip_planes,
|
||||
priority_planes.end());
|
||||
|
||||
// And re-sort the ov_set into its proper order.
|
||||
priority_planes.sort();
|
||||
|
||||
// Now create a new attrib reflecting these planeNodes.
|
||||
PT(ClipPlaneAttrib) attrib = new ClipPlaneAttrib;
|
||||
attrib->_on_planes.swap(priority_planes);
|
||||
|
||||
CPT(RenderAttrib) new_attrib = return_new(attrib);
|
||||
|
||||
// Finally, record this newly-created attrib in the map for next
|
||||
// time.
|
||||
CPT(ClipPlaneAttrib) planeNode_attrib = (const ClipPlaneAttrib *)new_attrib.p();
|
||||
((ClipPlaneAttrib *)this)->_filtered[max_clip_planes] = planeNode_attrib;
|
||||
return planeNode_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::issue
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -749,6 +818,20 @@ make_default_impl() const {
|
|||
return new ClipPlaneAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::sort_on_planes
|
||||
// Access: Private
|
||||
// Description: This is patterned after
|
||||
// TextureAttrib::sort_on_stages(), but since planeNodes
|
||||
// don't actually require sorting, this only empties the
|
||||
// _filtered map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ClipPlaneAttrib::
|
||||
sort_on_planes() {
|
||||
_sort_seq = PlaneNode::get_sort_seq();
|
||||
_filtered.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ClipPlaneAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@
|
|||
|
||||
#include "planeNode.h"
|
||||
#include "renderAttrib.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "nodePath.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ClipPlaneAttrib
|
||||
|
|
@ -92,6 +93,8 @@ PUBLISHED:
|
|||
CPT(RenderAttrib) add_off_plane(const NodePath &plane) const;
|
||||
CPT(RenderAttrib) remove_off_plane(const NodePath &plane) const;
|
||||
|
||||
CPT(ClipPlaneAttrib) filter_to_max(int max_clip_planes) const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
|
@ -102,10 +105,19 @@ protected:
|
|||
virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
INLINE void check_filtered() const;
|
||||
void sort_on_planes();
|
||||
|
||||
private:
|
||||
typedef ov_set<NodePath> Planes;
|
||||
Planes _on_planes, _off_planes;
|
||||
bool _off_all_planes;
|
||||
|
||||
typedef pmap< int, CPT(ClipPlaneAttrib) > Filtered;
|
||||
Filtered _filtered;
|
||||
|
||||
UpdateSeq _sort_seq;
|
||||
|
||||
static CPT(RenderAttrib) _empty_attrib;
|
||||
static CPT(RenderAttrib) _all_off_attrib;
|
||||
|
|
|
|||
|
|
@ -159,6 +159,21 @@ get_vector_to_light(LVector3f &result, const LPoint3f &,
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DirectionalLight::get_class_priority
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the relative priority associated with all
|
||||
// lights of this class. This priority is used to order
|
||||
// lights whose instance priority (get_priority()) is
|
||||
// the same--the idea is that other things being equal,
|
||||
// AmbientLights (for instance) are less important than
|
||||
// DirectionalLights.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int DirectionalLight::
|
||||
get_class_priority() const {
|
||||
return (int)CP_directional_priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DirectionalLight::bind
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ PUBLISHED:
|
|||
|
||||
INLINE const LVector3f &get_direction() const;
|
||||
INLINE void set_direction(const LVector3f &direction);
|
||||
|
||||
virtual int get_class_priority() const;
|
||||
|
||||
public:
|
||||
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ CData(const Light::CData ©) :
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Light::
|
||||
Light() {
|
||||
Light() :
|
||||
_priority(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -58,6 +60,7 @@ Light() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Light::
|
||||
Light(const Light ©) :
|
||||
_priority(copy._priority),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
|
@ -85,9 +88,58 @@ set_color(const Colorf &color) {
|
|||
mark_viz_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Light::set_priority
|
||||
// Access: Published
|
||||
// Description: Changes the relative importance of this light
|
||||
// relative to the other lights that are applied
|
||||
// simultaneously.
|
||||
//
|
||||
// The priority number is used to decide which of the
|
||||
// requested lights are to be selected for rendering
|
||||
// when more lights are requested than the hardware will
|
||||
// support. The highest-priority n lights are selected
|
||||
// for rendering.
|
||||
//
|
||||
// This is similar to TextureStage::set_priority().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Light::
|
||||
set_priority(int priority) {
|
||||
_priority = priority;
|
||||
|
||||
// Update the global flag to indicate that all LightAttribs in the
|
||||
// world must now re-sort their lists.
|
||||
_sort_seq++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Light::get_priority
|
||||
// Access: Published
|
||||
// Description: Returns the priority associated with this light. See
|
||||
// set_priority().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int Light::
|
||||
get_priority() const {
|
||||
return _priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Light::get_sort_seq
|
||||
// Access: Public, Static
|
||||
// Description: Returns a global sequence number that is incremented
|
||||
// any time any Light in the world changes sort
|
||||
// or priority. This is used by LightAttrib to
|
||||
// determine when it is necessary to re-sort its
|
||||
// internal array of stages.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq Light::
|
||||
get_sort_seq() {
|
||||
return _sort_seq;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Light::mark_viz_stale
|
||||
// Access: Public
|
||||
// Access: Protected
|
||||
// Description: Indicates that the internal visualization object will
|
||||
// need to be updated.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
UpdateSeq Light::_sort_seq;
|
||||
|
||||
TypeHandle Light::_type_handle;
|
||||
|
||||
|
||||
|
|
@ -128,6 +130,7 @@ fill_viz_geom(GeomNode *) {
|
|||
void Light::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
manager->write_cdata(dg, _cycler);
|
||||
dg.add_int32(_priority);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -140,4 +143,5 @@ write_datagram(BamWriter *manager, Datagram &dg) {
|
|||
void Light::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
manager->read_cdata(scan, _cycler);
|
||||
_priority = scan.get_int32();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "updateSeq.h"
|
||||
#include "geomNode.h"
|
||||
|
||||
class NodePath;
|
||||
|
|
@ -56,6 +57,10 @@ PUBLISHED:
|
|||
INLINE const Colorf &get_color() const;
|
||||
INLINE void set_color(const Colorf &color);
|
||||
|
||||
INLINE void set_priority(int priority);
|
||||
INLINE int get_priority() const;
|
||||
virtual int get_class_priority() const=0;
|
||||
|
||||
public:
|
||||
virtual void output(ostream &out) const=0;
|
||||
virtual void write(ostream &out, int indent_level) const=0;
|
||||
|
|
@ -68,11 +73,31 @@ public:
|
|||
|
||||
GeomNode *get_viz();
|
||||
|
||||
INLINE static UpdateSeq get_sort_seq();
|
||||
|
||||
protected:
|
||||
virtual void fill_viz_geom(GeomNode *viz_geom);
|
||||
INLINE void mark_viz_stale();
|
||||
|
||||
// This enumerated class defines the relative class priority of
|
||||
// different kinds of lights. This hierarchy is only used to
|
||||
// resolve multiple lights of the same priority specified by
|
||||
// set_priority(). In general, the first items in this list have a
|
||||
// lesser priority than later items.
|
||||
enum ClassPriority {
|
||||
CP_ambient_priority,
|
||||
CP_point_priority,
|
||||
CP_directional_priority,
|
||||
CP_spot_priority,
|
||||
};
|
||||
|
||||
private:
|
||||
// The priority is not cycled, because there's no real reason to do
|
||||
// so, and cycling it makes it difficult to synchronize with the
|
||||
// LightAttribs.
|
||||
int _priority;
|
||||
static UpdateSeq _sort_seq;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -133,3 +133,20 @@ INLINE bool LightAttrib::
|
|||
is_identity() const {
|
||||
return _on_lights.empty() && _off_lights.empty() && !_off_all_lights;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::check_filtered
|
||||
// Access: Private
|
||||
// Description: Confirms whether the _filtered table is still valid.
|
||||
// It may become invalid if someone calls
|
||||
// Light::set_priority().
|
||||
//
|
||||
// If the table is invalid, transparently empties it
|
||||
// before returning.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void LightAttrib::
|
||||
check_filtered() const {
|
||||
if (_sort_seq != Light::get_sort_seq()) {
|
||||
((LightAttrib *)this)->sort_on_lights();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lightAttrib.h"
|
||||
#include "ambientLight.h"
|
||||
#include "pandaNode.h"
|
||||
#include "nodePath.h"
|
||||
#include "graphicsStateGuardianBase.h"
|
||||
|
|
@ -30,6 +31,24 @@ CPT(RenderAttrib) LightAttrib::_empty_attrib;
|
|||
CPT(RenderAttrib) LightAttrib::_all_off_attrib;
|
||||
TypeHandle LightAttrib::_type_handle;
|
||||
|
||||
// This STL Function object is used in filter_to_max(), below, to sort
|
||||
// a list of Lights in reverse order by priority. In the case of two
|
||||
// lights with equal priority, the class priority is compared.
|
||||
class CompareLightPriorities {
|
||||
public:
|
||||
bool operator ()(const NodePath &a, const NodePath &b) const {
|
||||
nassertr(!a.is_empty() && !b.is_empty(), a < b);
|
||||
Light *la = a.node()->as_light();
|
||||
Light *lb = b.node()->as_light();
|
||||
nassertr(la != (Light *)NULL && lb != (Light *)NULL, a < b);
|
||||
|
||||
if (la->get_priority() != lb->get_priority()) {
|
||||
return la->get_priority() > lb->get_priority();
|
||||
}
|
||||
return la->get_class_priority() > lb->get_class_priority();
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::make
|
||||
// Access: Published, Static
|
||||
|
|
@ -448,6 +467,83 @@ remove_off_light(const NodePath &light) const {
|
|||
return return_new(attrib);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::filter_to_max
|
||||
// Access: Public
|
||||
// Description: Returns a new LightAttrib, very much like this one,
|
||||
// but with the number of on_lights reduced to be no
|
||||
// more than max_lights. The number of off_lights in
|
||||
// the new LightAttrib is undefined.
|
||||
//
|
||||
// The number of AmbientLights is not included in the
|
||||
// count. All AmbientLights in the original attrib are
|
||||
// always included in the result, regardless of the
|
||||
// value of max_lights.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(LightAttrib) LightAttrib::
|
||||
filter_to_max(int max_lights) const {
|
||||
if (max_lights < 0 || (int)_on_lights.size() <= max_lights) {
|
||||
// Trivial case: this LightAttrib qualifies.
|
||||
return this;
|
||||
}
|
||||
|
||||
// Since check_filtered() will clear the _filtered list if we are out
|
||||
// of date, we should call it first.
|
||||
check_filtered();
|
||||
|
||||
Filtered::const_iterator fi;
|
||||
fi = _filtered.find(max_lights);
|
||||
if (fi != _filtered.end()) {
|
||||
// Easy case: we have already computed this for this particular
|
||||
// LightAttrib.
|
||||
return (*fi).second;
|
||||
}
|
||||
|
||||
// Harder case: we have to compute it now. We must choose the n
|
||||
// lights with the highest priority in our list of lights.
|
||||
Lights priority_lights, ambient_lights;
|
||||
|
||||
// Separate the list of lights into ambient lights and other lights.
|
||||
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, this);
|
||||
if (np.node()->is_exact_type(AmbientLight::get_class_type())) {
|
||||
ambient_lights.push_back(np);
|
||||
} else {
|
||||
priority_lights.push_back(np);
|
||||
}
|
||||
}
|
||||
|
||||
// This sort function uses the STL function object defined above.
|
||||
sort(priority_lights.begin(), priority_lights.end(),
|
||||
CompareLightPriorities());
|
||||
|
||||
// Now lop off all of the lights after the first max_lights.
|
||||
priority_lights.erase(priority_lights.begin() + max_lights,
|
||||
priority_lights.end());
|
||||
|
||||
// Put the ambient lights back into the list.
|
||||
for (li = ambient_lights.begin(); li != ambient_lights.end(); ++li) {
|
||||
priority_lights.push_back(*li);
|
||||
}
|
||||
|
||||
// And re-sort the ov_set into its proper order.
|
||||
priority_lights.sort();
|
||||
|
||||
// Now create a new attrib reflecting these lights.
|
||||
PT(LightAttrib) attrib = new LightAttrib;
|
||||
attrib->_on_lights.swap(priority_lights);
|
||||
|
||||
CPT(RenderAttrib) new_attrib = return_new(attrib);
|
||||
|
||||
// Finally, record this newly-created attrib in the map for next
|
||||
// time.
|
||||
CPT(LightAttrib) light_attrib = (const LightAttrib *)new_attrib.p();
|
||||
((LightAttrib *)this)->_filtered[max_lights] = light_attrib;
|
||||
return light_attrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::issue
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -750,6 +846,20 @@ make_default_impl() const {
|
|||
return new LightAttrib;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::sort_on_lights
|
||||
// Access: Private
|
||||
// Description: This is patterned after
|
||||
// TextureAttrib::sort_on_stages(), but since lights
|
||||
// don't actually require sorting, this only empties the
|
||||
// _filtered map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void LightAttrib::
|
||||
sort_on_lights() {
|
||||
_sort_seq = Light::get_sort_seq();
|
||||
_filtered.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: LightAttrib::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@
|
|||
|
||||
#include "light.h"
|
||||
#include "renderAttrib.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "nodePath.h"
|
||||
#include "ordered_vector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : LightAttrib
|
||||
|
|
@ -90,6 +91,8 @@ PUBLISHED:
|
|||
CPT(RenderAttrib) add_off_light(const NodePath &light) const;
|
||||
CPT(RenderAttrib) remove_off_light(const NodePath &light) const;
|
||||
|
||||
CPT(LightAttrib) filter_to_max(int max_lights) const;
|
||||
|
||||
public:
|
||||
virtual void issue(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void output(ostream &out) const;
|
||||
|
|
@ -100,11 +103,20 @@ protected:
|
|||
virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const;
|
||||
virtual RenderAttrib *make_default_impl() const;
|
||||
|
||||
private:
|
||||
INLINE void check_filtered() const;
|
||||
void sort_on_lights();
|
||||
|
||||
private:
|
||||
typedef ov_set<NodePath> Lights;
|
||||
Lights _on_lights, _off_lights;
|
||||
bool _off_all_lights;
|
||||
|
||||
typedef pmap< int, CPT(LightAttrib) > Filtered;
|
||||
Filtered _filtered;
|
||||
|
||||
UpdateSeq _sort_seq;
|
||||
|
||||
static CPT(RenderAttrib) _empty_attrib;
|
||||
static CPT(RenderAttrib) _all_off_attrib;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,3 +61,53 @@ get_plane() const {
|
|||
CDReader cdata(_cycler);
|
||||
return cdata->_plane;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PlaneNode::set_priority
|
||||
// Access: Published
|
||||
// Description: Changes the relative importance of this PlaneNode
|
||||
// (when it is used as a clip plane) relative to the
|
||||
// other clip planes that are applied simultaneously.
|
||||
//
|
||||
// The priority number is used to decide which of the
|
||||
// requested clip planes are to be activated when more
|
||||
// clip planes are requested than the hardware will
|
||||
// support. The highest-priority n planes are selected
|
||||
// for rendering.
|
||||
//
|
||||
// This is similar to TextureStage::set_priority().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PlaneNode::
|
||||
set_priority(int priority) {
|
||||
_priority = priority;
|
||||
|
||||
// Update the global flag to indicate that all ClipPlaneAttribs in
|
||||
// the world must now re-sort their lists.
|
||||
_sort_seq++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PlaneNode::get_priority
|
||||
// Access: Published
|
||||
// Description: Returns the priority associated with this clip
|
||||
// plane. See set_priority().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PlaneNode::
|
||||
get_priority() const {
|
||||
return _priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PlaneNode::get_sort_seq
|
||||
// Access: Public, Static
|
||||
// Description: Returns a global sequence number that is incremented
|
||||
// any time any PlaneNode in the world changes sort
|
||||
// or priority. This is used by ClipPlaneAttrib to
|
||||
// determine when it is necessary to re-sort its
|
||||
// internal array of stages.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq PlaneNode::
|
||||
get_sort_seq() {
|
||||
return _sort_seq;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
UpdateSeq PlaneNode::_sort_seq;
|
||||
|
||||
TypeHandle PlaneNode::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -65,7 +67,8 @@ fillin(DatagramIterator &scan, BamReader *) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PlaneNode::
|
||||
PlaneNode(const string &name) :
|
||||
PandaNode(name)
|
||||
PandaNode(name),
|
||||
_priority(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +80,7 @@ PlaneNode(const string &name) :
|
|||
PlaneNode::
|
||||
PlaneNode(const PlaneNode ©) :
|
||||
PandaNode(copy),
|
||||
_priority(copy._priority),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
|
@ -151,6 +155,7 @@ void PlaneNode::
|
|||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
PandaNode::write_datagram(manager, dg);
|
||||
manager->write_cdata(dg, _cycler);
|
||||
dg.add_int32(_priority);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -184,4 +189,5 @@ void PlaneNode::
|
|||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
PandaNode::fillin(scan, manager);
|
||||
manager->read_cdata(scan, _cycler);
|
||||
_priority = scan.get_int32();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "plane.h"
|
||||
#include "pandaNode.h"
|
||||
#include "updateSeq.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PlaneNode
|
||||
|
|
@ -48,7 +49,19 @@ PUBLISHED:
|
|||
INLINE void set_plane(const Planef &plane);
|
||||
INLINE const Planef &get_plane() const;
|
||||
|
||||
INLINE void set_priority(int priority);
|
||||
INLINE int get_priority() const;
|
||||
|
||||
public:
|
||||
INLINE static UpdateSeq get_sort_seq();
|
||||
|
||||
private:
|
||||
// The priority is not cycled, because there's no real reason to do
|
||||
// so, and cycling it makes it difficult to synchronize with the
|
||||
// ClipPlaneAttribs.
|
||||
int _priority;
|
||||
static UpdateSeq _sort_seq;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -159,6 +159,21 @@ get_vector_to_light(LVector3f &result, const LPoint3f &from_object_point,
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointLight::get_class_priority
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the relative priority associated with all
|
||||
// lights of this class. This priority is used to order
|
||||
// lights whose instance priority (get_priority()) is
|
||||
// the same--the idea is that other things being equal,
|
||||
// AmbientLights (for instance) are less important than
|
||||
// DirectionalLights.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PointLight::
|
||||
get_class_priority() const {
|
||||
return (int)CP_point_priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointLight::bind
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ PUBLISHED:
|
|||
|
||||
INLINE const LPoint3f &get_point() const;
|
||||
INLINE void set_point(const LPoint3f &point);
|
||||
|
||||
virtual int get_class_priority() const;
|
||||
|
||||
public:
|
||||
virtual void bind(GraphicsStateGuardianBase *gsg, const NodePath &light,
|
||||
|
|
|
|||
|
|
@ -212,6 +212,21 @@ make_spot(int pixel_width, float full_radius, Colorf &fg, Colorf &bg) {
|
|||
return tex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Spotlight::get_class_priority
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns the relative priority associated with all
|
||||
// lights of this class. This priority is used to order
|
||||
// lights whose instance priority (get_priority()) is
|
||||
// the same--the idea is that other things being equal,
|
||||
// AmbientLights (for instance) are less important than
|
||||
// DirectionalLights.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Spotlight::
|
||||
get_class_priority() const {
|
||||
return (int)CP_spot_priority;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Spotlight::bind
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ PUBLISHED:
|
|||
INLINE const LVecBase3f &get_attenuation() const;
|
||||
INLINE void set_attenuation(const LVecBase3f &attenuation);
|
||||
|
||||
virtual int get_class_priority() const;
|
||||
|
||||
static PT(Texture) make_spot(int pixel_width, float full_radius,
|
||||
Colorf &fg, Colorf &bg);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ TypeHandle TextureAttrib::_type_handle;
|
|||
|
||||
// This STL Function object is used in filter_to_max(), below, to sort
|
||||
// a list of TextureStages in reverse order by priority and, within
|
||||
// prioirty, in order by sort.
|
||||
// priority, in order by sort.
|
||||
class CompareTextureStagePriorities {
|
||||
public:
|
||||
bool operator ()(const TextureStage *a, const TextureStage *b) const {
|
||||
|
|
@ -778,7 +778,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
// Function: TextureAttrib::sort_on_stages
|
||||
// Access: Private
|
||||
// Description: Sorts the list of stages so that they are listed in
|
||||
// render order.
|
||||
// render order. Also clears the _filtered map.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureAttrib::
|
||||
sort_on_stages() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue