mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
color-scale-via-lighting
This commit is contained in:
parent
00e2d94a05
commit
a2eb3859cb
@ -158,6 +158,17 @@ ConfigVariableBool auto_generate_mipmaps
|
||||
"false by default because some drivers (Intel) seem to do a "
|
||||
"poor job of generating mipmaps when needed."));
|
||||
|
||||
ConfigVariableBool color_scale_via_lighting
|
||||
("color-scale-via-lighting", true,
|
||||
PRC_DESC("When this is true, Panda will try to implement ColorAttribs and "
|
||||
"ColorScaleAttribs using the lighting interface, by "
|
||||
"creating a default material and/or an ambient light if "
|
||||
"necessary, even if lighting is ostensibly disabled. This "
|
||||
"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."));
|
||||
|
||||
ConfigVariableInt win_size
|
||||
("win-size", "640 480",
|
||||
PRC_DESC("This is the default size at which to open a new window. This "
|
||||
|
@ -57,6 +57,7 @@ extern EXPCL_PANDA ConfigVariableBool copy_texture_inverted;
|
||||
extern EXPCL_PANDA ConfigVariableBool window_inverted;
|
||||
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 ConfigVariableInt win_size;
|
||||
extern EXPCL_PANDA ConfigVariableInt win_origin;
|
||||
|
@ -316,6 +316,19 @@ get_supports_render_texture() const {
|
||||
return _supports_render_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_color_scale_via_lighting
|
||||
// Access: Published
|
||||
// Description: Returns true if this particular GSG can implement (or
|
||||
// would prefer to implement) set color and/or color
|
||||
// scale using materials and/or ambient lights, or
|
||||
// false if we need to actually munge the color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GraphicsStateGuardian::
|
||||
get_color_scale_via_lighting() const {
|
||||
return _color_scale_via_lighting;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::set_scene
|
||||
|
@ -131,6 +131,17 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
_supports_render_texture = false;
|
||||
|
||||
_supported_geom_rendering = 0;
|
||||
|
||||
// If this is true, then we can apply a color and/or color scale by
|
||||
// twiddling the material and/or ambient light (which could mean
|
||||
// enabling lighting even without a LightAttrib).
|
||||
_color_scale_via_lighting = color_scale_via_lighting;
|
||||
|
||||
if (!use_qpgeom) {
|
||||
// The old Geom interface doesn't really work too well with the
|
||||
// color_scale_via_lighting trick.
|
||||
_color_scale_via_lighting = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -223,6 +234,14 @@ reset() {
|
||||
_blend_mode_stale = false;
|
||||
_pending_texture = NULL;
|
||||
_texture_stale = false;
|
||||
_pending_light = NULL;
|
||||
_light_stale = false;
|
||||
_pending_material = NULL;
|
||||
_material_stale = false;
|
||||
|
||||
_has_material_force_color = false;
|
||||
_material_force_color.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
_light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -356,7 +375,7 @@ release_index_buffer(IndexBufferContext *) {
|
||||
// Description: Creates a new GeomMunger object to munge vertices
|
||||
// appropriate to this GSG for the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomMunger) GraphicsStateGuardian::
|
||||
PT(qpGeomMunger) GraphicsStateGuardian::
|
||||
get_geom_munger(const RenderState *state) {
|
||||
// The default implementation returns no munger at all, but
|
||||
// presumably, every kind of GSG needs some special munging action,
|
||||
@ -886,6 +905,12 @@ issue_color_scale(const ColorScaleAttrib *attrib) {
|
||||
if (_texture_involves_color_scale) {
|
||||
_texture_stale = true;
|
||||
}
|
||||
if (_color_scale_via_lighting) {
|
||||
_light_stale = true;
|
||||
_material_stale = true;
|
||||
|
||||
determine_light_color_scale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -929,153 +954,39 @@ issue_color(const ColorAttrib *attrib) {
|
||||
_vertex_colors_enabled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_color_scale_via_lighting) {
|
||||
_light_stale = true;
|
||||
_material_stale = true;
|
||||
|
||||
determine_light_color_scale();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::issue_light
|
||||
// Access: Public, Virtual
|
||||
// Description: The default implementation of issue_light() assumes
|
||||
// we have a limited number of hardware lights
|
||||
// available. This function assigns each light to a
|
||||
// different hardware light id, trying to keep each
|
||||
// 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.
|
||||
//
|
||||
// It will call apply_light() each time a light is
|
||||
// assigned to a particular id for the first time in a
|
||||
// given frame, and it will subsequently call
|
||||
// enable_light() to enable or disable each light as the
|
||||
// frame is rendered, as well as enable_lighting() to
|
||||
// enable or disable overall lighting.
|
||||
//
|
||||
// If this model of hardware lights with id's does not
|
||||
// apply to a particular graphics engine, it should
|
||||
// override this function to do something more
|
||||
// appropriate instead.
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
issue_light(const LightAttrib *attrib) {
|
||||
// Initialize the current ambient light total and newly enabled
|
||||
// light list
|
||||
Colorf cur_ambient_light(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
int i;
|
||||
int max_lights = (int)_light_info.size();
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
_light_info[i]._next_enabled = false;
|
||||
}
|
||||
// By default, we don't apply the light attrib right away, since
|
||||
// it might have a dependency on the current ColorScaleAttrib.
|
||||
_pending_light = attrib;
|
||||
_light_stale = true;
|
||||
}
|
||||
|
||||
bool any_bound = false;
|
||||
|
||||
int num_enabled = 0;
|
||||
int num_on_lights = attrib->get_num_on_lights();
|
||||
for (int li = 0; li < num_on_lights; li++) {
|
||||
NodePath light = attrib->get_on_light(li);
|
||||
nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL);
|
||||
Light *light_obj = light.node()->as_light();
|
||||
|
||||
num_enabled++;
|
||||
|
||||
// Lighting should be enabled before we apply any lights.
|
||||
enable_lighting(true);
|
||||
_lighting_enabled = true;
|
||||
_lighting_enabled_this_frame = true;
|
||||
|
||||
if (light_obj->get_type() == AmbientLight::get_class_type()) {
|
||||
// Ambient lights don't require specific light ids; simply add
|
||||
// in the ambient contribution to the current total
|
||||
cur_ambient_light += light_obj->get_color();
|
||||
|
||||
} 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++) {
|
||||
if (_light_info[i]._light == light) {
|
||||
// Light has already been bound to an id, we only need to
|
||||
// enable the light, not reapply it.
|
||||
cur_light_id = -2;
|
||||
enable_light(i, true);
|
||||
_light_info[i]._enabled = true;
|
||||
_light_info[i]._next_enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// See if there are any unbound light ids
|
||||
if (cur_light_id == -1) {
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
if (_light_info[i]._light.is_empty()) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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 (!attrib->has_on_light(_light_info[i]._light)) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
_light_info.push_back(LightInfo());
|
||||
max_lights++;
|
||||
nassertv(max_lights == (int)_light_info.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_light_id >= 0) {
|
||||
enable_light(cur_light_id, true);
|
||||
_light_info[cur_light_id]._enabled = true;
|
||||
_light_info[cur_light_id]._next_enabled = true;
|
||||
|
||||
if (!any_bound) {
|
||||
begin_bind_lights();
|
||||
any_bound = true;
|
||||
}
|
||||
|
||||
// This is the first time this frame that this light has been
|
||||
// bound to this particular id.
|
||||
light_obj->bind(this, light, cur_light_id);
|
||||
|
||||
} else if (cur_light_id == -1) {
|
||||
gsg_cat.warning()
|
||||
<< "Failed to bind " << light << " to id.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all unused lights
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
if (!_light_info[i]._next_enabled) {
|
||||
enable_light(i, false);
|
||||
_light_info[i]._enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no lights were enabled, disable lighting
|
||||
if (num_enabled == 0) {
|
||||
enable_lighting(false);
|
||||
_lighting_enabled = false;
|
||||
} else {
|
||||
set_ambient_light(cur_ambient_light);
|
||||
}
|
||||
|
||||
if (any_bound) {
|
||||
end_bind_lights();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::issue_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
issue_material(const MaterialAttrib *attrib) {
|
||||
// By default, we don't apply the material attrib right away, since
|
||||
// it might have a dependency on the current ColorScaleAttrib.
|
||||
_pending_material = attrib;
|
||||
_material_stale = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1278,6 +1189,181 @@ void GraphicsStateGuardian::
|
||||
bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::do_issue_light
|
||||
// Access: Protected
|
||||
// Description: This implementation of issue_light() assumes
|
||||
// we have a limited number of hardware lights
|
||||
// available. This function assigns each light to a
|
||||
// different hardware light id, trying to keep each
|
||||
// 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.
|
||||
//
|
||||
// It will call apply_light() each time a light is
|
||||
// assigned to a particular id for the first time in a
|
||||
// given frame, and it will subsequently call
|
||||
// enable_light() to enable or disable each light as the
|
||||
// frame is rendered, as well as enable_lighting() to
|
||||
// enable or disable overall lighting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
do_issue_light() {
|
||||
// Initialize the current ambient light total and newly enabled
|
||||
// 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++) {
|
||||
_light_info[i]._next_enabled = false;
|
||||
}
|
||||
|
||||
bool any_bound = false;
|
||||
|
||||
int num_enabled = 0;
|
||||
if (_pending_light != (LightAttrib *)NULL) {
|
||||
int num_on_lights = _pending_light->get_num_on_lights();
|
||||
for (int li = 0; li < num_on_lights; li++) {
|
||||
NodePath light = _pending_light->get_on_light(li);
|
||||
nassertv(!light.is_empty() && light.node()->as_light() != (Light *)NULL);
|
||||
Light *light_obj = light.node()->as_light();
|
||||
|
||||
num_enabled++;
|
||||
|
||||
// Lighting should be enabled before we apply any lights.
|
||||
enable_lighting(true);
|
||||
_lighting_enabled = true;
|
||||
_lighting_enabled_this_frame = true;
|
||||
|
||||
if (light_obj->get_type() == AmbientLight::get_class_type()) {
|
||||
// Ambient lights don't require specific light ids; simply add
|
||||
// in the ambient contribution to the current total
|
||||
cur_ambient_light += light_obj->get_color();
|
||||
|
||||
} 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++) {
|
||||
if (_light_info[i]._light == light) {
|
||||
// Light has already been bound to an id; reuse the same id.
|
||||
cur_light_id = -2;
|
||||
enable_light(i, true);
|
||||
_light_info[i]._enabled = true;
|
||||
_light_info[i]._next_enabled = true;
|
||||
light_obj->bind(this, light, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// See if there are any unbound light ids
|
||||
if (cur_light_id == -1) {
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
if (_light_info[i]._light.is_empty()) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
_light_info[i]._light = light;
|
||||
cur_light_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
_light_info.push_back(LightInfo());
|
||||
max_lights++;
|
||||
nassertv(max_lights == (int)_light_info.size());
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_light_id >= 0) {
|
||||
enable_light(cur_light_id, true);
|
||||
_light_info[cur_light_id]._enabled = true;
|
||||
_light_info[cur_light_id]._next_enabled = true;
|
||||
|
||||
if (!any_bound) {
|
||||
begin_bind_lights();
|
||||
any_bound = true;
|
||||
}
|
||||
|
||||
// This is the first time this frame that this light has been
|
||||
// bound to this particular id.
|
||||
light_obj->bind(this, light, cur_light_id);
|
||||
|
||||
} else if (cur_light_id == -1) {
|
||||
gsg_cat.warning()
|
||||
<< "Failed to bind " << light << " to id.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable all unused lights
|
||||
for (i = 0; i < max_lights; i++) {
|
||||
if (!_light_info[i]._next_enabled) {
|
||||
enable_light(i, false);
|
||||
_light_info[i]._enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// If no lights were enabled, disable lighting
|
||||
if (num_enabled == 0) {
|
||||
if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4f(1.0f, 1.0f, 1.0f, 1.0f))) {
|
||||
// Unless we need lighting anyway to apply a color or color
|
||||
// scale.
|
||||
enable_lighting(true);
|
||||
_lighting_enabled = true;
|
||||
_lighting_enabled_this_frame = true;
|
||||
set_ambient_light(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
|
||||
} else {
|
||||
enable_lighting(false);
|
||||
_lighting_enabled = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
set_ambient_light(cur_ambient_light);
|
||||
}
|
||||
|
||||
if (any_bound) {
|
||||
end_bind_lights();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::do_issue_material
|
||||
// Access: Protected, Virtual
|
||||
// Description: Should be overridden by derived classes to actually
|
||||
// apply the material saved in _pending_material.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
do_issue_material() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::do_issue_texture
|
||||
// Access: Protected, Virtual
|
||||
// Description: Should be overridden by derived classes to actually
|
||||
// apply the texture saved in _pending_texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
do_issue_texture() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
@ -1470,6 +1556,21 @@ finish_modify_state() {
|
||||
_blend_mode_stale = false;
|
||||
set_blend_mode();
|
||||
}
|
||||
|
||||
if (_texture_stale) {
|
||||
_texture_stale = false;
|
||||
do_issue_texture();
|
||||
}
|
||||
|
||||
if (_material_stale) {
|
||||
_material_stale = false;
|
||||
do_issue_material();
|
||||
}
|
||||
|
||||
if (_light_stale) {
|
||||
_light_stale = false;
|
||||
do_issue_light();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -1529,6 +1630,41 @@ panic_deactivate() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::determine_light_color_scale
|
||||
// Access: Protected
|
||||
// Description: Called whenever the color or color scale is changed,
|
||||
// if _color_scale_via_lighting is true. This will
|
||||
// rederive _material_force_color and _light_color_scale
|
||||
// appropriately.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
determine_light_color_scale() {
|
||||
if (_has_scene_graph_color) {
|
||||
// If we have a scene graph color, it, plus the color scale, goes
|
||||
// directly into the material; we don't color scale the
|
||||
// lights--this allows an alpha color scale to work properly.
|
||||
_has_material_force_color = true;
|
||||
_material_force_color = _scene_graph_color;
|
||||
_light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (!_color_blend_involves_color_scale && _color_scale_enabled) {
|
||||
_material_force_color.set(_scene_graph_color[0] * _current_color_scale[0],
|
||||
_scene_graph_color[1] * _current_color_scale[1],
|
||||
_scene_graph_color[2] * _current_color_scale[2],
|
||||
_scene_graph_color[3] * _current_color_scale[3]);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Otherise, leave the materials alone, but we might still scale
|
||||
// the lights.
|
||||
_has_material_force_color = false;
|
||||
_light_color_scale.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (!_color_blend_involves_color_scale && _color_scale_enabled) {
|
||||
_light_color_scale = _current_color_scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "colorWriteAttrib.h"
|
||||
#include "colorBlendAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "lightAttrib.h"
|
||||
#include "transparencyAttrib.h"
|
||||
#include "config_display.h"
|
||||
#include "qpgeomMunger.h"
|
||||
@ -100,6 +102,8 @@ PUBLISHED:
|
||||
|
||||
virtual int get_supported_geom_rendering() const;
|
||||
|
||||
INLINE bool get_color_scale_via_lighting() const;
|
||||
|
||||
public:
|
||||
INLINE bool set_scene(SceneSetup *scene_setup);
|
||||
INLINE SceneSetup *get_scene() const;
|
||||
@ -118,7 +122,7 @@ public:
|
||||
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *transform);
|
||||
@ -193,6 +197,7 @@ public:
|
||||
virtual void issue_color_scale(const ColorScaleAttrib *attrib);
|
||||
virtual void issue_color(const ColorAttrib *attrib);
|
||||
virtual void issue_light(const LightAttrib *attrib);
|
||||
virtual void issue_material(const MaterialAttrib *attrib);
|
||||
virtual void issue_color_write(const ColorWriteAttrib *attrib);
|
||||
virtual void issue_transparency(const TransparencyAttrib *attrib);
|
||||
virtual void issue_color_blend(const ColorBlendAttrib *attrib);
|
||||
@ -207,6 +212,10 @@ public:
|
||||
int light_id);
|
||||
|
||||
protected:
|
||||
void do_issue_light();
|
||||
virtual void do_issue_material();
|
||||
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);
|
||||
@ -231,6 +240,8 @@ protected:
|
||||
virtual void close_gsg();
|
||||
void panic_deactivate();
|
||||
|
||||
void determine_light_color_scale();
|
||||
|
||||
INLINE void set_properties(const FrameBufferProperties &properties);
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
@ -313,6 +324,14 @@ protected:
|
||||
|
||||
CPT(TextureAttrib) _pending_texture;
|
||||
bool _texture_stale;
|
||||
CPT(LightAttrib) _pending_light;
|
||||
bool _light_stale;
|
||||
CPT(MaterialAttrib) _pending_material;
|
||||
bool _material_stale;
|
||||
|
||||
bool _has_material_force_color;
|
||||
Colorf _material_force_color;
|
||||
LVecBase4f _light_color_scale;
|
||||
|
||||
bool _needs_reset;
|
||||
bool _closing_gsg;
|
||||
@ -332,6 +351,7 @@ protected:
|
||||
bool _supports_generate_mipmap;
|
||||
bool _supports_render_texture;
|
||||
int _supported_geom_rendering;
|
||||
bool _color_scale_via_lighting;
|
||||
|
||||
public:
|
||||
// Statistics
|
||||
|
@ -37,15 +37,56 @@ StandardMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
int num_components,
|
||||
StandardMunger::NumericType numeric_type,
|
||||
StandardMunger::Contents contents) :
|
||||
qpGeomMunger(gsg, state),
|
||||
_num_components(num_components),
|
||||
_numeric_type(numeric_type),
|
||||
_contents(contents)
|
||||
{
|
||||
_gsg = DCAST(GraphicsStateGuardian, gsg);
|
||||
_color = state->get_color();
|
||||
_color_scale = state->get_color_scale();
|
||||
_render_mode = state->get_render_mode();
|
||||
|
||||
_munge_color = false;
|
||||
_munge_color_scale = false;
|
||||
|
||||
CPT(ColorAttrib) color_attrib = state->get_color();
|
||||
CPT(ColorScaleAttrib) color_scale_attrib = state->get_color_scale();
|
||||
|
||||
if (color_attrib != (ColorAttrib *)NULL &&
|
||||
color_attrib->get_color_type() == ColorAttrib::T_flat) {
|
||||
|
||||
if (!_gsg->get_color_scale_via_lighting()) {
|
||||
// We only need to munge the color directly if the GSG says it
|
||||
// can't cheat the color via lighting (presumably, in this case,
|
||||
// by applying a material).
|
||||
_color = color_attrib->get_color();
|
||||
if (color_scale_attrib != (ColorScaleAttrib *)NULL &&
|
||||
color_scale_attrib->has_scale()) {
|
||||
const LVecBase4f &cs = color_scale_attrib->get_scale();
|
||||
_color.set(_color[0] * cs[0],
|
||||
_color[1] * cs[1],
|
||||
_color[2] * cs[2],
|
||||
_color[3] * cs[3]);
|
||||
}
|
||||
_munge_color = true;
|
||||
}
|
||||
|
||||
} 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] != 1.0f) {
|
||||
// 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.
|
||||
_munge_color_scale = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -67,25 +108,12 @@ CPT(qpGeomVertexData) StandardMunger::
|
||||
munge_data_impl(const qpGeomVertexData *data) {
|
||||
CPT(qpGeomVertexData) new_data = data;
|
||||
|
||||
if (_color != (ColorAttrib *)NULL &&
|
||||
_color->get_color_type() == ColorAttrib::T_flat) {
|
||||
Colorf color = _color->get_color();
|
||||
if (_color_scale != (ColorScaleAttrib *)NULL &&
|
||||
_color_scale->has_scale()) {
|
||||
const LVecBase4f &cs = _color_scale->get_scale();
|
||||
color.set(color[0] * cs[0],
|
||||
color[1] * cs[1],
|
||||
color[2] * cs[2],
|
||||
color[3] * cs[3]);
|
||||
}
|
||||
new_data = new_data->set_color(color, _num_components, _numeric_type,
|
||||
if (_munge_color) {
|
||||
new_data = new_data->set_color(_color, _num_components, _numeric_type,
|
||||
_contents);
|
||||
|
||||
} else if (_color_scale != (ColorScaleAttrib *)NULL &&
|
||||
_color_scale->has_scale()) {
|
||||
const LVecBase4f &cs = _color_scale->get_scale();
|
||||
new_data = new_data->scale_color(cs, _num_components, _numeric_type,
|
||||
_contents);
|
||||
} else if (_munge_color_scale) {
|
||||
new_data = new_data->scale_color(_color_scale, _num_components,
|
||||
_numeric_type, _contents);
|
||||
}
|
||||
|
||||
qpGeomVertexAnimationSpec animation = new_data->get_format()->get_animation();
|
||||
@ -189,17 +217,30 @@ munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &vertex_data) {
|
||||
int StandardMunger::
|
||||
compare_to_impl(const qpGeomMunger *other) const {
|
||||
const StandardMunger *om = DCAST(StandardMunger, other);
|
||||
if (_color != om->_color) {
|
||||
return _color < om->_color ? -1 : 1;
|
||||
}
|
||||
if (_color_scale != om->_color_scale) {
|
||||
return _color_scale < om->_color_scale ? -1 : 1;
|
||||
}
|
||||
if (_render_mode != om->_render_mode) {
|
||||
return _render_mode < om->_render_mode ? -1 : 1;
|
||||
}
|
||||
|
||||
return qpGeomMunger::compare_to_impl(other);
|
||||
if (_munge_color != om->_munge_color) {
|
||||
return (int)_munge_color - (int)om->_munge_color;
|
||||
}
|
||||
if (_munge_color_scale != om->_munge_color_scale) {
|
||||
return (int)_munge_color_scale - (int)om->_munge_color_scale;
|
||||
}
|
||||
if (_munge_color) {
|
||||
int compare = _color.compare_to(om->_color);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
if (_munge_color_scale) {
|
||||
int compare = _color_scale.compare_to(om->_color_scale);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return StateMunger::compare_to_impl(other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -215,12 +256,43 @@ compare_to_impl(const qpGeomMunger *other) const {
|
||||
int StandardMunger::
|
||||
geom_compare_to_impl(const qpGeomMunger *other) const {
|
||||
const StandardMunger *om = DCAST(StandardMunger, other);
|
||||
if (_color != om->_color) {
|
||||
return _color < om->_color ? -1 : 1;
|
||||
if (_munge_color != om->_munge_color) {
|
||||
return (int)_munge_color - (int)om->_munge_color;
|
||||
}
|
||||
if (_color_scale != om->_color_scale) {
|
||||
return _color_scale < om->_color_scale ? -1 : 1;
|
||||
if (_munge_color_scale != om->_munge_color_scale) {
|
||||
return (int)_munge_color_scale - (int)om->_munge_color_scale;
|
||||
}
|
||||
if (_munge_color) {
|
||||
int compare = _color.compare_to(om->_color);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
if (_munge_color_scale) {
|
||||
int compare = _color_scale.compare_to(om->_color_scale);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return qpGeomMunger::geom_compare_to_impl(other);
|
||||
return StateMunger::geom_compare_to_impl(other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StandardMunger::munge_state_impl
|
||||
// Access: Protectes, Virtual
|
||||
// Description: Given an input state, returns the munged state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) StandardMunger::
|
||||
munge_state_impl(const RenderState *state) {
|
||||
CPT(RenderState) munged_state = state;
|
||||
|
||||
if (_munge_color) {
|
||||
munged_state = munged_state->remove_attrib(ColorAttrib::get_class_type());
|
||||
munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_type());
|
||||
} else if (_munge_color_scale) {
|
||||
munged_state = munged_state->remove_attrib(ColorScaleAttrib::get_class_type());
|
||||
}
|
||||
|
||||
return munged_state;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define STANDARDMUNGER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomMunger.h"
|
||||
#include "stateMunger.h"
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
@ -36,7 +36,7 @@
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA StandardMunger : public qpGeomMunger {
|
||||
class EXPCL_PANDA StandardMunger : public StateMunger {
|
||||
public:
|
||||
StandardMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state,
|
||||
int num_components, NumericType numeric_type,
|
||||
@ -48,24 +48,29 @@ protected:
|
||||
virtual int compare_to_impl(const qpGeomMunger *other) const;
|
||||
virtual bool munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
|
||||
virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
|
||||
virtual CPT(RenderState) munge_state_impl(const RenderState *state);
|
||||
|
||||
private:
|
||||
int _num_components;
|
||||
NumericType _numeric_type;
|
||||
Contents _contents;
|
||||
CPT(GraphicsStateGuardian) _gsg;
|
||||
CPT(ColorAttrib) _color;
|
||||
CPT(ColorScaleAttrib) _color_scale;
|
||||
CPT(RenderModeAttrib) _render_mode;
|
||||
|
||||
bool _munge_color;
|
||||
bool _munge_color_scale;
|
||||
|
||||
Colorf _color;
|
||||
LVecBase4f _color_scale;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomMunger::init_type();
|
||||
StateMunger::init_type();
|
||||
register_type(_type_handle, "StandardMunger",
|
||||
qpGeomMunger::get_class_type());
|
||||
StateMunger::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "spotlight.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "texGenAttrib.h"
|
||||
#include "lightAttrib.h"
|
||||
#include "shadeModelAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "transparencyAttrib.h"
|
||||
@ -413,8 +412,8 @@ dx_init(void) {
|
||||
_has_scene_graph_color = false;
|
||||
|
||||
// Apply a default material when materials are turned off.
|
||||
Material empty;
|
||||
apply_material(&empty);
|
||||
_pending_material = NULL;
|
||||
do_issue_material();
|
||||
|
||||
// GL stuff that hasnt been translated to DX
|
||||
// none of these are implemented
|
||||
@ -3556,7 +3555,7 @@ release_index_buffer(IndexBufferContext *ibc) {
|
||||
// Description: Creates a new GeomMunger object to munge vertices
|
||||
// appropriate to this GSG for the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomMunger) DXGraphicsStateGuardian8::
|
||||
PT(qpGeomMunger) DXGraphicsStateGuardian8::
|
||||
get_geom_munger(const RenderState *state) {
|
||||
PT(DXGeomMunger8) munger = new DXGeomMunger8(this, state);
|
||||
return qpGeomMunger::register_munger(munger);
|
||||
@ -3704,44 +3703,6 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::apply_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
apply_material(const Material *material) {
|
||||
D3DMATERIAL8 cur_material;
|
||||
cur_material.Diffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data());
|
||||
cur_material.Ambient = *(D3DCOLORVALUE *)(material->get_ambient().get_data());
|
||||
cur_material.Specular = *(D3DCOLORVALUE *)(material->get_specular().get_data());
|
||||
cur_material.Emissive = *(D3DCOLORVALUE *)(material->get_emission().get_data());
|
||||
cur_material.Power = material->get_shininess();
|
||||
|
||||
_pD3DDevice->SetMaterial(&cur_material);
|
||||
|
||||
if (material->has_diffuse()) {
|
||||
// If the material specifies an diffuse color, use it.
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
// Otherwise, the diffuse color comes from the object color.
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
}
|
||||
if (material->has_ambient()) {
|
||||
// If the material specifies an ambient color, use it.
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
// Otherwise, the ambient color comes from the object color.
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
}
|
||||
|
||||
if (material->get_local()) {
|
||||
_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, TRUE);
|
||||
} else {
|
||||
_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::apply_fog
|
||||
// Access: Public, Virtual
|
||||
@ -3977,42 +3938,6 @@ issue_shade_model(const ShadeModelAttrib *attrib) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::issue_texture
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
issue_texture(const TextureAttrib *attrib) {
|
||||
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
|
||||
if (attrib->is_off()) {
|
||||
enable_texturing(false);
|
||||
} else {
|
||||
Texture *tex = attrib->get_texture();
|
||||
nassertv(tex != (Texture *)NULL);
|
||||
|
||||
TextureContext *tc = tex->prepare_now(_prepared_objects, this);
|
||||
apply_texture(tc);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::issue_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
issue_material(const MaterialAttrib *attrib) {
|
||||
const Material *material = attrib->get_material();
|
||||
if (material != (const Material *)NULL) {
|
||||
apply_material(material);
|
||||
} else {
|
||||
// Apply a default material when materials are turned off.
|
||||
Material empty;
|
||||
apply_material(&empty);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::issue_render_mode
|
||||
// Access: Public, Virtual
|
||||
@ -4218,7 +4143,7 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
||||
black.r = black.g = black.b = black.a = 0.0f;
|
||||
D3DLIGHT8 alight;
|
||||
alight.Type = D3DLIGHT_POINT;
|
||||
alight.Diffuse = *(D3DCOLORVALUE *)(light_obj->get_color().get_data());
|
||||
alight.Diffuse = get_light_color(light_obj);
|
||||
alight.Ambient = black ;
|
||||
alight.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
@ -4267,7 +4192,7 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
||||
ZeroMemory(&alight, sizeof(D3DLIGHT8));
|
||||
|
||||
alight.Type = D3DLIGHT_DIRECTIONAL;
|
||||
alight.Diffuse = *(D3DCOLORVALUE *)(light_obj->get_color().get_data());
|
||||
alight.Diffuse = get_light_color(light_obj);
|
||||
alight.Ambient = black ;
|
||||
alight.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
@ -4318,7 +4243,7 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
||||
|
||||
alight.Type = D3DLIGHT_SPOT;
|
||||
alight.Ambient = black ;
|
||||
alight.Diffuse = *(D3DCOLORVALUE *)(light_obj->get_color().get_data());
|
||||
alight.Diffuse = get_light_color(light_obj);
|
||||
alight.Specular = *(D3DCOLORVALUE *)(light_obj->get_specular_color().get_data());
|
||||
|
||||
alight.Position = *(D3DVECTOR *)pos.get_data();
|
||||
@ -4531,6 +4456,25 @@ get_index_type(qpGeom::NumericType numeric_type) {
|
||||
return D3DFMT_INDEX16;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::get_light_color
|
||||
// Access: Public
|
||||
// Description: Returns the array of four floats that should be
|
||||
// issued as the light's color, as scaled by the current
|
||||
// value of _light_color_scale, in the case of
|
||||
// color_scale_via_lighting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const D3DCOLORVALUE &DXGraphicsStateGuardian8::
|
||||
get_light_color(Light *light) const {
|
||||
static Colorf c;
|
||||
c = light->get_color();
|
||||
c.set(c[0] * _light_color_scale[0],
|
||||
c[1] * _light_color_scale[1],
|
||||
c[2] * _light_color_scale[2],
|
||||
c[3] * _light_color_scale[3]);
|
||||
return *(D3DCOLORVALUE *)c.get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::set_draw_buffer
|
||||
// Access: Protected
|
||||
@ -4652,6 +4596,86 @@ do_auto_rescale_normal() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::do_issue_texture
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
do_issue_texture() {
|
||||
DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
|
||||
|
||||
CPT(TextureAttrib) new_texture = _pending_texture->filter_to_max(_max_texture_stages);
|
||||
|
||||
if (new_texture->is_off()) {
|
||||
enable_texturing(false);
|
||||
} else {
|
||||
Texture *tex = new_texture->get_texture();
|
||||
nassertv(tex != (Texture *)NULL);
|
||||
|
||||
TextureContext *tc = tex->prepare_now(_prepared_objects, this);
|
||||
apply_texture(tc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::do_issue_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
do_issue_material() {
|
||||
static Material empty;
|
||||
const Material *material;
|
||||
if (_pending_material == (MaterialAttrib *)NULL ||
|
||||
_pending_material->is_off()) {
|
||||
material = ∅
|
||||
} else {
|
||||
material = _pending_material->get_material();
|
||||
}
|
||||
|
||||
D3DMATERIAL8 cur_material;
|
||||
cur_material.Diffuse = *(D3DCOLORVALUE *)(material->get_diffuse().get_data());
|
||||
cur_material.Ambient = *(D3DCOLORVALUE *)(material->get_ambient().get_data());
|
||||
cur_material.Specular = *(D3DCOLORVALUE *)(material->get_specular().get_data());
|
||||
cur_material.Emissive = *(D3DCOLORVALUE *)(material->get_emission().get_data());
|
||||
cur_material.Power = material->get_shininess();
|
||||
|
||||
if (material->has_diffuse()) {
|
||||
// If the material specifies an diffuse color, use it.
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
// Otherwise, the diffuse color comes from the object color.
|
||||
if (_has_material_force_color) {
|
||||
cur_material.Diffuse = *(D3DCOLORVALUE *)_material_force_color.get_data();
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
}
|
||||
}
|
||||
if (material->has_ambient()) {
|
||||
// If the material specifies an ambient color, use it.
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
// Otherwise, the ambient color comes from the object color.
|
||||
if (_has_material_force_color) {
|
||||
cur_material.Ambient = *(D3DCOLORVALUE *)_material_force_color.get_data();
|
||||
_pD3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
|
||||
} else {
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
|
||||
}
|
||||
}
|
||||
|
||||
_pD3DDevice->SetMaterial(&cur_material);
|
||||
|
||||
if (material->get_local()) {
|
||||
_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, TRUE);
|
||||
} else {
|
||||
_pD3DDevice->SetRenderState(D3DRS_LOCALVIEWER, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
@ -4693,7 +4717,13 @@ enable_lighting(bool enable) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
set_ambient_light(const Colorf &color) {
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENT, Colorf_to_D3DCOLOR(color));
|
||||
Colorf c = color;
|
||||
c.set(c[0] * _light_color_scale[0],
|
||||
c[1] * _light_color_scale[1],
|
||||
c[2] * _light_color_scale[2],
|
||||
c[3] * _light_color_scale[3]);
|
||||
|
||||
_pD3DDevice->SetRenderState(D3DRS_AMBIENT, Colorf_to_D3DCOLOR(c));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -115,20 +115,17 @@ public:
|
||||
void apply_index_buffer(IndexBufferContext *ibc);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
|
||||
const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
virtual void apply_fog(Fog *fog);
|
||||
|
||||
virtual void issue_transform(const TransformState *transform);
|
||||
virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
|
||||
virtual void issue_texture(const TextureAttrib *attrib);
|
||||
virtual void issue_material(const MaterialAttrib *attrib);
|
||||
virtual void issue_render_mode(const RenderModeAttrib *attrib);
|
||||
virtual void issue_rescale_normal(const RescaleNormalAttrib *attrib);
|
||||
virtual void issue_alpha_test(const AlphaTestAttrib *attrib);
|
||||
@ -160,6 +157,8 @@ public:
|
||||
|
||||
static D3DFORMAT get_index_type(qpGeom::NumericType numeric_type);
|
||||
|
||||
const D3DCOLORVALUE &get_light_color(Light *light) const;
|
||||
|
||||
public:
|
||||
// recreate_tex_callback needs these to be public
|
||||
DXScreenData *_pScrn;
|
||||
@ -168,6 +167,8 @@ public:
|
||||
D3DPRESENT_PARAMETERS _PresReset; // This is built during reset device
|
||||
|
||||
protected:
|
||||
virtual void do_issue_material();
|
||||
|
||||
virtual bool slot_new_light(int light_id);
|
||||
virtual void enable_lighting(bool enable);
|
||||
virtual void set_ambient_light(const Colorf &color);
|
||||
@ -192,6 +193,7 @@ protected:
|
||||
static CPT(RenderState) get_flat_state();
|
||||
|
||||
void do_auto_rescale_normal();
|
||||
virtual void do_issue_texture();
|
||||
|
||||
bool _bDXisReady;
|
||||
HRESULT _last_testcooplevel_result;
|
||||
@ -204,10 +206,10 @@ protected:
|
||||
bool _auto_rescale_normal;
|
||||
|
||||
void GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize,
|
||||
void *pIndexSpace,DWORD dwIndexSpaceByteSize,
|
||||
D3DXVECTOR3 *pCenter, float fRadius,
|
||||
DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz,
|
||||
DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize);
|
||||
void *pIndexSpace,DWORD dwIndexSpaceByteSize,
|
||||
D3DXVECTOR3 *pCenter, float fRadius,
|
||||
DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz,
|
||||
DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize);
|
||||
HRESULT ReleaseAllDeviceObjects(void);
|
||||
HRESULT RecreateAllDeviceObjects(void);
|
||||
HRESULT DeleteAllDeviceObjects(void);
|
||||
|
@ -861,8 +861,8 @@ reset() {
|
||||
cfa->issue(this);
|
||||
ta->issue(this);
|
||||
|
||||
Material empty;
|
||||
apply_material(&empty);
|
||||
_pending_material = NULL;
|
||||
do_issue_material();
|
||||
|
||||
if (CLP(cheap_textures)) {
|
||||
GLCAT.info()
|
||||
@ -1157,7 +1157,8 @@ draw_point(GeomPoint *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1227,7 +1228,8 @@ draw_line(GeomLine *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1304,7 +1306,8 @@ draw_linestrip(GeomLinestrip *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1677,7 +1680,8 @@ draw_polygon(GeomPolygon *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1758,7 +1762,8 @@ draw_tri(GeomTri *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1837,7 +1842,8 @@ draw_quad(GeomQuad *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -1920,7 +1926,8 @@ draw_tristrip(GeomTristrip *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -2021,7 +2028,8 @@ draw_trifan(GeomTrifan *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -2119,7 +2127,8 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
|
||||
|
||||
GeomIssuer::IssueColor *issue_color;
|
||||
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled) {
|
||||
if (_color_blend_involves_color_scale || !_color_scale_enabled ||
|
||||
_color_scale_via_lighting) {
|
||||
issue_color = issue_color_gl;
|
||||
} else {
|
||||
issue_color = issue_scaled_color_gl;
|
||||
@ -3206,7 +3215,7 @@ setup_primitive(const qpGeomPrimitive *data) {
|
||||
// Description: Creates a new GeomMunger object to munge vertices
|
||||
// appropriate to this GSG for the indicated state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomMunger) CLP(GraphicsStateGuardian)::
|
||||
PT(qpGeomMunger) CLP(GraphicsStateGuardian)::
|
||||
get_geom_munger(const RenderState *state) {
|
||||
PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
|
||||
return qpGeomMunger::register_munger(munger);
|
||||
@ -3403,52 +3412,6 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::apply_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_material(const Material *material) {
|
||||
GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
|
||||
|
||||
GLP(Materialfv)(face, GL_SPECULAR, material->get_specular().get_data());
|
||||
GLP(Materialfv)(face, GL_EMISSION, material->get_emission().get_data());
|
||||
GLP(Materialf)(face, GL_SHININESS, material->get_shininess());
|
||||
|
||||
if (material->has_ambient() && material->has_diffuse()) {
|
||||
// The material has both an ambient and diffuse specified. This
|
||||
// means we do not need glMaterialColor().
|
||||
GLP(Disable)(GL_COLOR_MATERIAL);
|
||||
GLP(Materialfv)(face, GL_AMBIENT, material->get_ambient().get_data());
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, material->get_diffuse().get_data());
|
||||
|
||||
} else if (material->has_ambient()) {
|
||||
// The material specifies an ambient, but not a diffuse component.
|
||||
// The diffuse component comes from the object's color.
|
||||
GLP(Materialfv)(face, GL_AMBIENT, material->get_ambient().get_data());
|
||||
GLP(ColorMaterial)(face, GL_DIFFUSE);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
|
||||
} else if (material->has_diffuse()) {
|
||||
// The material specifies a diffuse, but not an ambient component.
|
||||
// The ambient component comes from the object's color.
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, material->get_diffuse().get_data());
|
||||
GLP(ColorMaterial)(face, GL_AMBIENT);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
|
||||
} else {
|
||||
// The material specifies neither a diffuse nor an ambient
|
||||
// component. Both components come from the object's color.
|
||||
GLP(ColorMaterial)(face, GL_AMBIENT_AND_DIFFUSE);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
GLP(LightModeli)(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
|
||||
GLP(LightModeli)(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::apply_fog
|
||||
// Access: Public, Virtual
|
||||
@ -3594,24 +3557,6 @@ issue_cg_shader_bind(const CgShaderAttrib *attrib) {
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::issue_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
issue_material(const MaterialAttrib *attrib) {
|
||||
const Material *material = attrib->get_material();
|
||||
if (material != (const Material *)NULL) {
|
||||
apply_material(material);
|
||||
} else {
|
||||
// Apply a default material when materials are turned off.
|
||||
Material empty;
|
||||
apply_material(&empty);
|
||||
}
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::issue_render_mode
|
||||
// Access: Public, Virtual
|
||||
@ -3903,6 +3848,77 @@ issue_depth_offset(const DepthOffsetAttrib *attrib) {
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::do_issue_material
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
do_issue_material() {
|
||||
static Material empty;
|
||||
const Material *material;
|
||||
if (_pending_material == (MaterialAttrib *)NULL ||
|
||||
_pending_material->is_off()) {
|
||||
material = ∅
|
||||
} else {
|
||||
material = _pending_material->get_material();
|
||||
}
|
||||
|
||||
GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
|
||||
|
||||
GLP(Materialfv)(face, GL_SPECULAR, material->get_specular().get_data());
|
||||
GLP(Materialfv)(face, GL_EMISSION, material->get_emission().get_data());
|
||||
GLP(Materialf)(face, GL_SHININESS, material->get_shininess());
|
||||
|
||||
if (material->has_ambient() && material->has_diffuse()) {
|
||||
// The material has both an ambient and diffuse specified. This
|
||||
// means we do not need glMaterialColor().
|
||||
GLP(Disable)(GL_COLOR_MATERIAL);
|
||||
GLP(Materialfv)(face, GL_AMBIENT, material->get_ambient().get_data());
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, material->get_diffuse().get_data());
|
||||
|
||||
} else if (material->has_ambient()) {
|
||||
// The material specifies an ambient, but not a diffuse component.
|
||||
// The diffuse component comes from the object's color.
|
||||
GLP(Materialfv)(face, GL_AMBIENT, material->get_ambient().get_data());
|
||||
if (_has_material_force_color) {
|
||||
GLP(Disable)(GL_COLOR_MATERIAL);
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, _material_force_color.get_data());
|
||||
} else {
|
||||
GLP(ColorMaterial)(face, GL_DIFFUSE);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
} else if (material->has_diffuse()) {
|
||||
// The material specifies a diffuse, but not an ambient component.
|
||||
// The ambient component comes from the object's color.
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, material->get_diffuse().get_data());
|
||||
if (_has_material_force_color) {
|
||||
GLP(Disable)(GL_COLOR_MATERIAL);
|
||||
GLP(Materialfv)(face, GL_AMBIENT, _material_force_color.get_data());
|
||||
} else {
|
||||
GLP(ColorMaterial)(face, GL_AMBIENT);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
} else {
|
||||
// The material specifies neither a diffuse nor an ambient
|
||||
// component. Both components come from the object's color.
|
||||
if (_has_material_force_color) {
|
||||
GLP(Disable)(GL_COLOR_MATERIAL);
|
||||
GLP(Materialfv)(face, GL_AMBIENT, _material_force_color.get_data());
|
||||
GLP(Materialfv)(face, GL_DIFFUSE, _material_force_color.get_data());
|
||||
} else {
|
||||
GLP(ColorMaterial)(face, GL_AMBIENT_AND_DIFFUSE);
|
||||
GLP(Enable)(GL_COLOR_MATERIAL);
|
||||
}
|
||||
}
|
||||
|
||||
GLP(LightModeli)(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
|
||||
GLP(LightModeli)(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::bind_light
|
||||
// Access: Public, Virtual
|
||||
@ -3916,7 +3932,7 @@ bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
|
||||
GLenum id = get_light_id(light_id);
|
||||
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
|
||||
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
|
||||
|
||||
// Position needs to specify x, y, z, and w
|
||||
@ -3956,7 +3972,7 @@ bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
|
||||
GLenum id = get_light_id( light_id );
|
||||
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
|
||||
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
|
||||
|
||||
// Position needs to specify x, y, z, and w.
|
||||
@ -4000,7 +4016,7 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
||||
GLenum id = get_light_id(light_id);
|
||||
static const Colorf black(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
GLP(Lightfv)(id, GL_AMBIENT, black.get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, light_obj->get_color().get_data());
|
||||
GLP(Lightfv)(id, GL_DIFFUSE, get_light_color(light_obj));
|
||||
GLP(Lightfv)(id, GL_SPECULAR, light_obj->get_specular_color().get_data());
|
||||
|
||||
// Position needs to specify x, y, z, and w
|
||||
@ -4984,6 +5000,25 @@ issue_scaled_color(const Colorf &color) const {
|
||||
GLP(Color4fv)(transformed.get_data());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::get_light_color
|
||||
// Access: Public
|
||||
// Description: Returns the array of four floats that should be
|
||||
// issued as the light's color, as scaled by the current
|
||||
// value of _light_color_scale, in the case of
|
||||
// color_scale_via_lighting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const float *CLP(GraphicsStateGuardian)::
|
||||
get_light_color(Light *light) const {
|
||||
static Colorf c;
|
||||
c = light->get_color();
|
||||
c.set(c[0] * _light_color_scale[0],
|
||||
c[1] * _light_color_scale[1],
|
||||
c[2] * _light_color_scale[2],
|
||||
c[3] * _light_color_scale[3]);
|
||||
return c.get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::slot_new_light
|
||||
// Access: Protected, Virtual
|
||||
@ -5029,7 +5064,12 @@ enable_lighting(bool enable) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
set_ambient_light(const Colorf &color) {
|
||||
GLP(LightModelfv)(GL_LIGHT_MODEL_AMBIENT, color.get_data());
|
||||
Colorf c = color;
|
||||
c.set(c[0] * _light_color_scale[0],
|
||||
c[1] * _light_color_scale[1],
|
||||
c[2] * _light_color_scale[2],
|
||||
c[3] * _light_color_scale[3]);
|
||||
GLP(LightModelfv)(GL_LIGHT_MODEL_AMBIENT, c.get_data());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -5306,12 +5346,6 @@ void CLP(GraphicsStateGuardian)::
|
||||
finish_modify_state() {
|
||||
GraphicsStateGuardian::finish_modify_state();
|
||||
|
||||
// Apply the texture, if it needs to be reapplied.
|
||||
if (_texture_stale) {
|
||||
_texture_stale = false;
|
||||
do_issue_texture();
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -5656,7 +5690,7 @@ do_auto_rescale_normal() {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::do_issue_texture
|
||||
// Access: Protected
|
||||
// Access: Protected, Virtual
|
||||
// Description: This is called by finish_modify_state() when the
|
||||
// texture state has changed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -123,19 +123,17 @@ public:
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
const unsigned char *setup_primitive(const qpGeomPrimitive *data);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void framebuffer_copy_to_texture
|
||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
virtual bool framebuffer_copy_to_ram
|
||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
|
||||
virtual void apply_material(const Material *material);
|
||||
void apply_fog(Fog *fog);
|
||||
|
||||
virtual void issue_transform(const TransformState *transform);
|
||||
virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
|
||||
virtual void issue_material(const MaterialAttrib *attrib);
|
||||
virtual void issue_render_mode(const RenderModeAttrib *attrib);
|
||||
virtual void issue_antialias(const AntialiasAttrib *);
|
||||
virtual void issue_rescale_normal(const RescaleNormalAttrib *attrib);
|
||||
@ -152,6 +150,8 @@ public:
|
||||
virtual void issue_cg_shader_bind(const CgShaderAttrib *attrib);
|
||||
#endif
|
||||
|
||||
virtual void do_issue_material();
|
||||
|
||||
virtual void bind_light(PointLight *light_obj, const NodePath &light,
|
||||
int light_id);
|
||||
virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
|
||||
@ -170,6 +170,7 @@ public:
|
||||
void dump_state(void);
|
||||
|
||||
void issue_scaled_color(const Colorf &color) const;
|
||||
const float *get_light_color(Light *light) const;
|
||||
|
||||
INLINE static bool report_errors(int line, const char *source_file);
|
||||
INLINE void report_my_errors(int line, const char *source_file);
|
||||
@ -256,7 +257,7 @@ protected:
|
||||
static CPT(RenderState) get_flat_state();
|
||||
|
||||
void do_auto_rescale_normal();
|
||||
void do_issue_texture();
|
||||
virtual void do_issue_texture();
|
||||
void specify_texture(Texture *tex);
|
||||
void apply_texture(TextureContext *tc);
|
||||
bool upload_texture(CLP(TextureContext) *gtc);
|
||||
|
@ -162,11 +162,11 @@ ConfigVariableBool display_list_animation
|
||||
|
||||
ConfigVariableBool connect_triangle_strips
|
||||
("connect-triangle-strips", true,
|
||||
PRC_DESC("Set this true to set a batch of triangle strips to the graphics "
|
||||
PRC_DESC("Set this true to send a batch of triangle strips to the graphics "
|
||||
"card as one long triangle strip, connected by degenerate "
|
||||
"triangles, or false to send them as separate triangle strips "
|
||||
"with no degenerate triangles. In many cases, using one long "
|
||||
"triangle strip can help performance by reducing the number "
|
||||
"with no degenerate triangles. On PC hardware, using one long "
|
||||
"triangle strip may help performance by reducing the number "
|
||||
"of separate graphics calls that have to be made."));
|
||||
|
||||
ConfigVariableBool use_qpgeom
|
||||
|
@ -24,10 +24,10 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Material::
|
||||
Material() {
|
||||
_ambient.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
_ambient.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
_diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
_specular.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
_emission.set(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
_specular.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_emission.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_shininess = 0.0;
|
||||
_flags = 0;
|
||||
}
|
||||
|
@ -633,81 +633,6 @@ transform_vertices(const LMatrix4f &mat) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::munge_geom
|
||||
// Access: Published
|
||||
// Description: Applies the indicated munger to the geom and its
|
||||
// data, and returns a (possibly different) geom and
|
||||
// data, according to the munger's whim.
|
||||
//
|
||||
// The assumption is that for a particular geom and a
|
||||
// particular munger, the result will always be the
|
||||
// same; so this result may be cached.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
munge_geom(const qpGeomMunger *munger,
|
||||
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const {
|
||||
CPT(qpGeomVertexData) source_data = data;
|
||||
|
||||
// Look up the munger in our cache--maybe we've recently applied it.
|
||||
{
|
||||
CDReader cdata(_cycler);
|
||||
CacheEntry temp_entry(source_data, munger);
|
||||
temp_entry.local_object();
|
||||
Cache::const_iterator ci = cdata->_cache.find(&temp_entry);
|
||||
if (ci != cdata->_cache.end()) {
|
||||
CacheEntry *entry = (*ci);
|
||||
|
||||
if (get_modified() <= entry->_geom_result->get_modified() &&
|
||||
data->get_modified() <= entry->_data_result->get_modified()) {
|
||||
// The cache entry is still good; use it.
|
||||
|
||||
// Record a cache hit, so this element will stay in the cache a
|
||||
// while longer.
|
||||
entry->refresh();
|
||||
result = entry->_geom_result;
|
||||
data = entry->_data_result;
|
||||
return;
|
||||
}
|
||||
|
||||
// The cache entry is stale, remove it.
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Cache entry " << *entry << " is stale, removing.\n";
|
||||
}
|
||||
entry->erase();
|
||||
CDWriter cdataw(((qpGeom *)this)->_cycler, cdata);
|
||||
cdataw->_cache.erase(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, invoke the munger.
|
||||
PStatTimer timer(qpGeomMunger::_munge_pcollector);
|
||||
|
||||
result = this;
|
||||
if (munger != (qpGeomMunger *)NULL) {
|
||||
data = munger->munge_data(data);
|
||||
((qpGeomMunger *)munger)->munge_geom_impl(result, data);
|
||||
}
|
||||
|
||||
{
|
||||
// Record the new result in the cache.
|
||||
CacheEntry *entry;
|
||||
{
|
||||
CDWriter cdata(((qpGeom *)this)->_cycler);
|
||||
entry = new CacheEntry((qpGeom *)this, source_data, munger,
|
||||
result, data);
|
||||
bool inserted = cdata->_cache.insert(entry).second;
|
||||
nassertv(inserted);
|
||||
}
|
||||
|
||||
// And tell the cache manager about the new entry. (It might
|
||||
// immediately request a delete from the cache of the thing we
|
||||
// just added.)
|
||||
entry->record();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::check_valid
|
||||
// Access: Published
|
||||
|
@ -105,9 +105,6 @@ PUBLISHED:
|
||||
// Temporarily virtual.
|
||||
virtual void transform_vertices(const LMatrix4f &mat);
|
||||
|
||||
void munge_geom(const qpGeomMunger *munger,
|
||||
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const;
|
||||
|
||||
// Temporarily virtual.
|
||||
virtual bool check_valid() const;
|
||||
|
||||
@ -227,6 +224,7 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CacheEntry;
|
||||
friend class qpGeomMunger;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeom &obj);
|
||||
|
@ -45,7 +45,7 @@ is_registered() const {
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomMunger) qpGeomMunger::
|
||||
INLINE PT(qpGeomMunger) qpGeomMunger::
|
||||
register_munger(qpGeomMunger *munger) {
|
||||
return get_registry()->register_munger(munger);
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ PStatCollector qpGeomMunger::_munge_pcollector("*:Munge");
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomMunger::
|
||||
qpGeomMunger(const GraphicsStateGuardianBase *, const RenderState *) :
|
||||
qpGeomMunger() :
|
||||
_is_registered(false)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
@ -92,6 +92,79 @@ remove_data(const qpGeomVertexData *data) {
|
||||
nassertv(_is_registered);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::munge_geom
|
||||
// Access: Published
|
||||
// Description: Applies the indicated munger to the geom and its
|
||||
// data, and returns a (possibly different) geom and
|
||||
// data, according to the munger's whim.
|
||||
//
|
||||
// The assumption is that for a particular geom and a
|
||||
// particular munger, the result will always be the
|
||||
// same; so this result may be cached.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
munge_geom(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data) {
|
||||
CPT(qpGeomVertexData) source_data = data;
|
||||
|
||||
// Look up the munger in the geom's cache--maybe we've recently
|
||||
// applied it.
|
||||
{
|
||||
qpGeom::CDReader cdata(geom->_cycler);
|
||||
qpGeom::CacheEntry temp_entry(source_data, this);
|
||||
temp_entry.local_object();
|
||||
qpGeom::Cache::const_iterator ci = cdata->_cache.find(&temp_entry);
|
||||
if (ci != cdata->_cache.end()) {
|
||||
qpGeom::CacheEntry *entry = (*ci);
|
||||
|
||||
if (geom->get_modified() <= entry->_geom_result->get_modified() &&
|
||||
data->get_modified() <= entry->_data_result->get_modified()) {
|
||||
// The cache entry is still good; use it.
|
||||
|
||||
// Record a cache hit, so this element will stay in the cache a
|
||||
// while longer.
|
||||
entry->refresh();
|
||||
geom = entry->_geom_result;
|
||||
data = entry->_data_result;
|
||||
return;
|
||||
}
|
||||
|
||||
// The cache entry is stale, remove it.
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Cache entry " << *entry << " is stale, removing.\n";
|
||||
}
|
||||
entry->erase();
|
||||
qpGeom::CDWriter cdataw(((qpGeom *)geom.p())->_cycler, cdata);
|
||||
cdataw->_cache.erase(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, invoke the munger.
|
||||
PStatTimer timer(_munge_pcollector);
|
||||
|
||||
CPT(qpGeom) orig_geom = geom;
|
||||
data = munge_data(data);
|
||||
munge_geom_impl(geom, data);
|
||||
|
||||
{
|
||||
// Record the new result in the cache.
|
||||
qpGeom::CacheEntry *entry;
|
||||
{
|
||||
qpGeom::CDWriter cdata(((qpGeom *)orig_geom.p())->_cycler);
|
||||
entry = new qpGeom::CacheEntry((qpGeom *)orig_geom.p(), source_data, this,
|
||||
geom, data);
|
||||
bool inserted = cdata->_cache.insert(entry).second;
|
||||
nassertv(inserted);
|
||||
}
|
||||
|
||||
// And tell the cache manager about the new entry. (It might
|
||||
// immediately request a delete from the cache of the thing we
|
||||
// just added.)
|
||||
entry->record();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::do_munge_format
|
||||
// Access: Protected
|
||||
@ -286,7 +359,7 @@ Registry() {
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomMunger) qpGeomMunger::Registry::
|
||||
PT(qpGeomMunger) qpGeomMunger::Registry::
|
||||
register_munger(qpGeomMunger *munger) {
|
||||
if (munger->is_registered()) {
|
||||
return munger;
|
||||
|
@ -60,13 +60,13 @@ class qpGeom;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomMunger : public TypedReferenceCount, public qpGeomEnums {
|
||||
public:
|
||||
qpGeomMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state);
|
||||
qpGeomMunger();
|
||||
qpGeomMunger(const qpGeomMunger ©);
|
||||
void operator = (const qpGeomMunger ©);
|
||||
virtual ~qpGeomMunger();
|
||||
|
||||
INLINE bool is_registered() const;
|
||||
INLINE static CPT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
INLINE static PT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
|
||||
INLINE CPT(qpGeomVertexFormat) munge_format(const qpGeomVertexFormat *format,
|
||||
const qpGeomVertexAnimationSpec &animation) const;
|
||||
@ -74,7 +74,7 @@ public:
|
||||
INLINE CPT(qpGeomVertexData) munge_data(const qpGeomVertexData *data) const;
|
||||
void remove_data(const qpGeomVertexData *data);
|
||||
|
||||
// Also see Geom::munge_geom() for the primary interface.
|
||||
void munge_geom(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
|
||||
|
||||
public:
|
||||
INLINE int compare_to(const qpGeomMunger &other) const;
|
||||
@ -132,7 +132,7 @@ private:
|
||||
class EXPCL_PANDA Registry {
|
||||
public:
|
||||
Registry();
|
||||
CPT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
PT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
void unregister_munger(qpGeomMunger *munger);
|
||||
|
||||
Mungers _mungers;
|
||||
|
@ -145,7 +145,7 @@ public:
|
||||
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data)=0;
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc)=0;
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state)=0;
|
||||
virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state)=0;
|
||||
|
||||
virtual void set_state_and_transform(const RenderState *state,
|
||||
const TransformState *transform)=0;
|
||||
@ -205,8 +205,6 @@ public:
|
||||
virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex)=0;
|
||||
virtual void framebuffer_release_texture(GraphicsOutput *win, Texture *tex)=0;
|
||||
|
||||
virtual void apply_material(const Material *material)=0;
|
||||
|
||||
virtual CoordinateSystem get_internal_coordinate_system() const=0;
|
||||
|
||||
virtual void issue_transform(const TransformState *) { }
|
||||
|
@ -91,6 +91,7 @@
|
||||
shadeModelAttrib.I shadeModelAttrib.h \
|
||||
showBoundsEffect.I showBoundsEffect.h \
|
||||
spotlight.I spotlight.h \
|
||||
stateMunger.I stateMunger.h \
|
||||
switchNode.I switchNode.h \
|
||||
texMatrixAttrib.I texMatrixAttrib.h \
|
||||
texProjectorEffect.I texProjectorEffect.h \
|
||||
@ -188,6 +189,7 @@
|
||||
shadeModelAttrib.cxx \
|
||||
showBoundsEffect.cxx \
|
||||
spotlight.cxx \
|
||||
stateMunger.cxx \
|
||||
switchNode.cxx \
|
||||
texMatrixAttrib.cxx \
|
||||
texProjectorEffect.cxx \
|
||||
@ -281,6 +283,7 @@
|
||||
shadeModelAttrib.I shadeModelAttrib.h \
|
||||
showBoundsEffect.I showBoundsEffect.h \
|
||||
spotlight.I spotlight.h \
|
||||
stateMunger.I stateMunger.h \
|
||||
switchNode.I switchNode.h \
|
||||
texMatrixAttrib.I texMatrixAttrib.h \
|
||||
texProjectorEffect.I texProjectorEffect.h \
|
||||
|
@ -82,6 +82,7 @@
|
||||
#include "shadeModelAttrib.h"
|
||||
#include "showBoundsEffect.h"
|
||||
#include "spotlight.h"
|
||||
#include "stateMunger.h"
|
||||
#include "switchNode.h"
|
||||
#include "texMatrixAttrib.h"
|
||||
#include "texProjectorEffect.h"
|
||||
@ -320,6 +321,7 @@ init_libpgraph() {
|
||||
ShadeModelAttrib::init_type();
|
||||
ShowBoundsEffect::init_type();
|
||||
Spotlight::init_type();
|
||||
StateMunger::init_type();
|
||||
SwitchNode::init_type();
|
||||
TexMatrixAttrib::init_type();
|
||||
TexProjectorEffect::init_type();
|
||||
|
@ -63,13 +63,13 @@ get_bin(int bin_index) {
|
||||
// if we haven't already created one for this state;
|
||||
// otherwise, it will return the existing one.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomMunger) CullResult::
|
||||
INLINE PT(qpGeomMunger) CullResult::
|
||||
get_geom_munger(const RenderState *state) {
|
||||
Mungers::iterator mi = _mungers.find(state);
|
||||
if (mi != _mungers.end()) {
|
||||
return (*mi).second;
|
||||
}
|
||||
CPT(qpGeomMunger) munger = _gsg->get_geom_munger(state);
|
||||
PT(qpGeomMunger) munger = _gsg->get_geom_munger(state);
|
||||
_mungers.insert(Mungers::value_type(state, munger));
|
||||
return munger;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
|
||||
private:
|
||||
CullBin *make_new_bin(int bin_index);
|
||||
INLINE CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
INLINE PT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
static CPT(RenderState) get_binary_state();
|
||||
static CPT(RenderState) get_dual_transparent_state();
|
||||
@ -75,7 +75,7 @@ private:
|
||||
|
||||
GraphicsStateGuardianBase *_gsg;
|
||||
|
||||
typedef pmap<CPT(RenderState), CPT(qpGeomMunger) > Mungers;
|
||||
typedef pmap<CPT(RenderState), PT(qpGeomMunger) > Mungers;
|
||||
Mungers _mungers;
|
||||
|
||||
typedef pvector< PT(CullBin) > Bins;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "cullTraverser.h"
|
||||
#include "sceneSetup.h"
|
||||
#include "lens.h"
|
||||
#include "stateMunger.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "qpgeomVertexWriter.h"
|
||||
#include "qpgeomVertexReader.h"
|
||||
@ -42,7 +43,7 @@ TypeHandle CullableObject::_type_handle;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CullableObject::
|
||||
munge_geom(GraphicsStateGuardianBase *gsg,
|
||||
const qpGeomMunger *munger, const CullTraverser *traverser) {
|
||||
qpGeomMunger *munger, const CullTraverser *traverser) {
|
||||
if (_geom != (Geom *)NULL) {
|
||||
// Temporary test and dcast until the experimental Geom rewrite
|
||||
// becomes the actual Geom rewrite.
|
||||
@ -73,7 +74,12 @@ munge_geom(GraphicsStateGuardianBase *gsg,
|
||||
|
||||
// Now invoke the munger to ensure the resulting geometry is in
|
||||
// a GSG-friendly form.
|
||||
qpgeom->munge_geom(munger, qpgeom, _munged_data);
|
||||
munger->munge_geom(qpgeom, _munged_data);
|
||||
|
||||
StateMunger *state_munger;
|
||||
DCAST_INTO_V(state_munger, munger);
|
||||
_state = state_munger->munge_state(_state);
|
||||
|
||||
CPT(qpGeomVertexData) animated_vertices =
|
||||
_munged_data->animate_vertices();
|
||||
#ifndef NDEBUG
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
INLINE bool has_decals() const;
|
||||
|
||||
void munge_geom(GraphicsStateGuardianBase *gsg,
|
||||
const qpGeomMunger *munger, const CullTraverser *traverser);
|
||||
qpGeomMunger *munger, const CullTraverser *traverser);
|
||||
INLINE void draw(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
public:
|
||||
@ -77,7 +77,7 @@ PUBLISHED:
|
||||
|
||||
public:
|
||||
CPT(Geom) _geom;
|
||||
CPT(qpGeomMunger) _munger;
|
||||
PT(qpGeomMunger) _munger;
|
||||
CPT(qpGeomVertexData) _munged_data;
|
||||
CPT(RenderState) _state;
|
||||
CPT(TransformState) _transform;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "shadeModelAttrib.cxx"
|
||||
#include "showBoundsEffect.cxx"
|
||||
#include "spotlight.cxx"
|
||||
#include "stateMunger.cxx"
|
||||
#include "switchNode.cxx"
|
||||
#include "texMatrixAttrib.cxx"
|
||||
#include "texProjectorEffect.cxx"
|
||||
|
18
panda/src/pgraph/stateMunger.I
Normal file
18
panda/src/pgraph/stateMunger.I
Normal file
@ -0,0 +1,18 @@
|
||||
// Filename: stateMunger.I
|
||||
// Created by: drose (04May05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
50
panda/src/pgraph/stateMunger.cxx
Normal file
50
panda/src/pgraph/stateMunger.cxx
Normal file
@ -0,0 +1,50 @@
|
||||
// Filename: stateMunger.cxx
|
||||
// Created by: drose (04May05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stateMunger.h"
|
||||
|
||||
TypeHandle StateMunger::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StateMunger::munge_state
|
||||
// Access: Public
|
||||
// Description: Given an input state, returns the munged state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) StateMunger::
|
||||
munge_state(const RenderState *state) {
|
||||
CPT(RenderState) ptstate = state;
|
||||
StateMap::iterator mi = _state_map.find(ptstate);
|
||||
if (mi != _state_map.end()) {
|
||||
return (*mi).second;
|
||||
}
|
||||
|
||||
CPT(RenderState) result = munge_state_impl(state);
|
||||
_state_map[ptstate] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: StateMunger::munge_state_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Given an input state, returns the munged state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(RenderState) StateMunger::
|
||||
munge_state_impl(const RenderState *state) {
|
||||
return state;
|
||||
}
|
65
panda/src/pgraph/stateMunger.h
Normal file
65
panda/src/pgraph/stateMunger.h
Normal file
@ -0,0 +1,65 @@
|
||||
// Filename: stateMunger.h
|
||||
// Created by: drose (04May05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef STATEMUNGER_H
|
||||
#define STATEMUNGER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomMunger.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : StateMunger
|
||||
// Description : This is just a simple derivative of GeomMunger that
|
||||
// adds the ability to munge states. That functionality
|
||||
// can't be declared in the base class, since it doesn't
|
||||
// really know about RenderState.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA StateMunger : public qpGeomMunger {
|
||||
public:
|
||||
CPT(RenderState) munge_state(const RenderState *state);
|
||||
|
||||
protected:
|
||||
CPT(RenderState) munge_state_impl(const RenderState *state);
|
||||
|
||||
typedef pmap<CPT(RenderState), CPT(RenderState) > StateMap;
|
||||
StateMap _state_map;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomMunger::init_type();
|
||||
register_type(_type_handle, "StateMunger",
|
||||
qpGeomMunger::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "stateMunger.I"
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user