mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
lighting
This commit is contained in:
parent
1764ae7a7a
commit
4fb98a7f95
@ -62,6 +62,18 @@ ConfigVariableDouble speedtree_cull_cell_size
|
|||||||
"while increasing the number of trees that are rendered "
|
"while increasing the number of trees that are rendered "
|
||||||
"per call."));
|
"per call."));
|
||||||
|
|
||||||
|
ConfigVariableBool speedtree_5_2_stf
|
||||||
|
("speedtree-5-2-stf",
|
||||||
|
#if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 2)
|
||||||
|
true,
|
||||||
|
#else
|
||||||
|
false,
|
||||||
|
#endif
|
||||||
|
PRC_DESC("The format of the STF file changed in SpeedTree version 5.2. "
|
||||||
|
"Specify true here to read STF files in the new file format, or "
|
||||||
|
"false to read STF files in the pre-5.2 file format."));
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: init_libspeedtree
|
// Function: init_libspeedtree
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -31,6 +31,7 @@ extern ConfigVariableBool speedtree_allow_horizontal_billboards;
|
|||||||
extern ConfigVariableInt speedtree_max_num_visible_cells;
|
extern ConfigVariableInt speedtree_max_num_visible_cells;
|
||||||
extern ConfigVariableInt speedtree_max_billboard_images_by_base;
|
extern ConfigVariableInt speedtree_max_billboard_images_by_base;
|
||||||
extern ConfigVariableDouble speedtree_cull_cell_size;
|
extern ConfigVariableDouble speedtree_cull_cell_size;
|
||||||
|
extern ConfigVariableBool speedtree_5_2_stf;
|
||||||
|
|
||||||
extern EXPCL_PANDASPEEDTREE void init_libspeedtree();
|
extern EXPCL_PANDASPEEDTREE void init_libspeedtree();
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "geomDrawCallbackData.h"
|
#include "geomDrawCallbackData.h"
|
||||||
#include "graphicsStateGuardian.h"
|
#include "graphicsStateGuardian.h"
|
||||||
#include "textureAttrib.h"
|
#include "textureAttrib.h"
|
||||||
|
#include "lightAttrib.h"
|
||||||
|
#include "directionalLight.h"
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "deg_2_rad.h"
|
#include "deg_2_rad.h"
|
||||||
|
|
||||||
@ -45,8 +47,13 @@ TypeHandle SpeedTreeNode::DrawCallback::_type_handle;
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
SpeedTreeNode::
|
SpeedTreeNode::
|
||||||
SpeedTreeNode(const string &name) :
|
SpeedTreeNode(const string &name) :
|
||||||
PandaNode(name),
|
PandaNode(name)
|
||||||
_forest(*(new SpeedTree::CForestRender)) // HACK! SpeedTree doesn't destruct unused CForestRender objects correctly. Temporarily leaking these things until SpeedTree is fixed.
|
#ifdef ST_DELETE_FOREST_HACK
|
||||||
|
// Early versions of SpeedTree don't destruct unused CForestRender
|
||||||
|
// objects correctly. To avoid crashes, we have to leak these
|
||||||
|
// things.
|
||||||
|
, _forest(*(new SpeedTree::CForestRender))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
init_node();
|
init_node();
|
||||||
// For now, set an infinite bounding volume. Maybe in the future
|
// For now, set an infinite bounding volume. Maybe in the future
|
||||||
@ -373,8 +380,16 @@ add_from_stf(istream &in, const Filename &pathname,
|
|||||||
in >> num_instances;
|
in >> num_instances;
|
||||||
for (int ni = 0; ni < num_instances && in && !in.eof(); ++ni) {
|
for (int ni = 0; ni < num_instances && in && !in.eof(); ++ni) {
|
||||||
LPoint3f pos;
|
LPoint3f pos;
|
||||||
float rotate, scale, elev_min, elev_max, slope_min, slope_max;
|
float rotate, scale;
|
||||||
in >> pos[0] >> pos[1] >> pos[2] >> rotate >> scale >> elev_min >> elev_max >> slope_min >> slope_max;
|
in >> pos[0] >> pos[1] >> pos[2] >> rotate >> scale;
|
||||||
|
|
||||||
|
if (!speedtree_5_2_stf) {
|
||||||
|
// 5.1 or earlier stf files also included these additional
|
||||||
|
// values, which we will ignore:
|
||||||
|
float elev_min, elev_max, slope_min, slope_max;
|
||||||
|
in >> elev_min >> elev_max >> slope_min >> slope_max;
|
||||||
|
}
|
||||||
|
|
||||||
if (tree != NULL) {
|
if (tree != NULL) {
|
||||||
add_instance(tree, STTransform(pos, rad_2_deg(rotate), scale));
|
add_instance(tree, STTransform(pos, rad_2_deg(rotate), scale));
|
||||||
}
|
}
|
||||||
@ -382,11 +397,17 @@ add_from_stf(istream &in, const Filename &pathname,
|
|||||||
in >> os_filename;
|
in >> os_filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consume any whitespace at the end of the file.
|
||||||
|
in >> ws;
|
||||||
|
|
||||||
if (!in.eof()) {
|
if (!in.eof()) {
|
||||||
// If we didn't read all the way to end-of-file, there was an
|
// If we didn't read all the way to end-of-file, there was an
|
||||||
// error.
|
// error.
|
||||||
|
in.clear();
|
||||||
|
string text;
|
||||||
|
in >> text;
|
||||||
speedtree_cat.error()
|
speedtree_cat.error()
|
||||||
<< "Syntax error in " << pathname << "\n";
|
<< "Unexpected text in " << pathname << " at \"" << text << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,8 +452,13 @@ authorize(const string &license) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
SpeedTreeNode::
|
SpeedTreeNode::
|
||||||
SpeedTreeNode(const SpeedTreeNode ©) :
|
SpeedTreeNode(const SpeedTreeNode ©) :
|
||||||
PandaNode(copy),
|
PandaNode(copy)
|
||||||
_forest(*(new SpeedTree::CForestRender)) // HACK! SpeedTree doesn't destruct unused CForestRender objects correctly. Temporarily leaking these things until SpeedTree is fixed.
|
#ifdef ST_DELETE_FOREST_HACK
|
||||||
|
// Early versions of SpeedTree don't destruct unused CForestRender
|
||||||
|
// objects correctly. To avoid crashes, we have to leak these
|
||||||
|
// things.
|
||||||
|
, _forest(*(new SpeedTree::CForestRender))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
init_node();
|
init_node();
|
||||||
|
|
||||||
@ -456,6 +482,17 @@ SpeedTreeNode(const SpeedTreeNode ©) :
|
|||||||
mark_internal_bounds_stale();
|
mark_internal_bounds_stale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SpeedTreeNode::Destructor
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
SpeedTreeNode::
|
||||||
|
~SpeedTreeNode() {
|
||||||
|
// Help reduce memory waste from ST_DELETE_FOREST_HACK.
|
||||||
|
_forest.ClearInstances();
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: SpeedTreeNode::make_copy
|
// Function: SpeedTreeNode::make_copy
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -527,8 +564,8 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||||||
|
|
||||||
// Compute the modelview and camera transforms, to pass to the
|
// Compute the modelview and camera transforms, to pass to the
|
||||||
// SpeedTree CView structure.
|
// SpeedTree CView structure.
|
||||||
CPT(TransformState) modelview = data.get_modelview_transform(trav);
|
CPT(TransformState) orig_modelview = data.get_modelview_transform(trav);
|
||||||
modelview = gsg->get_cs_transform()->compose(modelview);
|
CPT(TransformState) modelview = gsg->get_cs_transform()->compose(orig_modelview);
|
||||||
CPT(TransformState) camera_transform = modelview->invert_compose(TransformState::make_identity());
|
CPT(TransformState) camera_transform = modelview->invert_compose(TransformState::make_identity());
|
||||||
const LMatrix4f &modelview_mat = modelview->get_mat();
|
const LMatrix4f &modelview_mat = modelview->get_mat();
|
||||||
const LPoint3f &camera_pos = camera_transform->get_pos();
|
const LPoint3f &camera_pos = camera_transform->get_pos();
|
||||||
@ -543,6 +580,40 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||||||
SpeedTree::Mat4x4(modelview_mat.get_data()),
|
SpeedTree::Mat4x4(modelview_mat.get_data()),
|
||||||
lens->get_near(), lens->get_far());
|
lens->get_near(), lens->get_far());
|
||||||
|
|
||||||
|
// Convert the render state to SpeedTree's input.
|
||||||
|
const RenderState *state = data._state;
|
||||||
|
|
||||||
|
// Check texture state. If all textures are disabled, then we ask
|
||||||
|
// SpeedTree to disable textures.
|
||||||
|
bool show_textures = true;
|
||||||
|
const TextureAttrib *ta = DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()));
|
||||||
|
if (ta != (TextureAttrib *)NULL) {
|
||||||
|
show_textures = !ta->has_all_off();
|
||||||
|
}
|
||||||
|
_forest.EnableTexturing(show_textures);
|
||||||
|
|
||||||
|
// Check lighting state. SpeedTree only supports a single
|
||||||
|
// directional light; we look for a directional light in the
|
||||||
|
// lighting state and pass its direction to SpeedTree.
|
||||||
|
NodePath light;
|
||||||
|
const LightAttrib *la = DCAST(LightAttrib, state->get_attrib(LightAttrib::get_class_slot()));
|
||||||
|
if (la != (LightAttrib *)NULL) {
|
||||||
|
light = la->get_most_important_light();
|
||||||
|
}
|
||||||
|
if (!light.is_empty() && light.node()->is_of_type(DirectionalLight::get_class_type())) {
|
||||||
|
DirectionalLight *light_obj = DCAST(DirectionalLight, light.node());
|
||||||
|
|
||||||
|
CPT(TransformState) transform = light.get_transform(trav->get_scene()->get_scene_root().get_parent());
|
||||||
|
LVector3f dir = light_obj->get_direction() * transform->get_mat();
|
||||||
|
_forest.SetLightDir(SpeedTree::Vec3(dir[0], dir[1], dir[2]));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// No light. But there's no way to turn off lighting in
|
||||||
|
// SpeedTree. In lieu of this, we just shine a light from
|
||||||
|
// above.
|
||||||
|
_forest.SetLightDir(SpeedTree::Vec3(0.0, 0.0, -1.0));
|
||||||
|
}
|
||||||
|
|
||||||
if (!_needs_repopulate) {
|
if (!_needs_repopulate) {
|
||||||
// Don't bother culling now unless we're correctly fully
|
// Don't bother culling now unless we're correctly fully
|
||||||
// populated. (Culling won't be accurate unless the forest has
|
// populated. (Culling won't be accurate unless the forest has
|
||||||
@ -550,7 +621,6 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
|
|||||||
// populate.)
|
// populate.)
|
||||||
_forest.CullAndComputeLOD(_view, _visible_trees);
|
_forest.CullAndComputeLOD(_view, _visible_trees);
|
||||||
}
|
}
|
||||||
// cerr << _visible_trees.m_aVisibleCells.size() << " visible cells\n";
|
|
||||||
|
|
||||||
// Recurse onto the node's children.
|
// Recurse onto the node's children.
|
||||||
return true;
|
return true;
|
||||||
@ -857,16 +927,6 @@ draw_callback(CallbackData *data) {
|
|||||||
GeomDrawCallbackData *geom_cbdata;
|
GeomDrawCallbackData *geom_cbdata;
|
||||||
DCAST_INTO_V(geom_cbdata, data);
|
DCAST_INTO_V(geom_cbdata, data);
|
||||||
|
|
||||||
// Check the input state.
|
|
||||||
const RenderState *state = geom_cbdata->get_object()->_state;
|
|
||||||
|
|
||||||
bool show_textures = true;
|
|
||||||
const TextureAttrib *texattrib = DCAST(TextureAttrib, state->get_attrib(TextureAttrib::get_class_slot()));
|
|
||||||
if (texattrib != (TextureAttrib *)NULL) {
|
|
||||||
show_textures = !texattrib->has_all_off();
|
|
||||||
}
|
|
||||||
_forest.EnableTexturing(show_textures);
|
|
||||||
|
|
||||||
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, geom_cbdata->get_gsg());
|
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, geom_cbdata->get_gsg());
|
||||||
|
|
||||||
setup_for_render(gsg);
|
setup_for_render(gsg);
|
||||||
@ -889,6 +949,10 @@ draw_callback(CallbackData *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_forest.EndRender();
|
_forest.EndRender();
|
||||||
|
|
||||||
|
// SpeedTree leaves the graphics state indeterminate. But this
|
||||||
|
// doesn't help?
|
||||||
|
geom_cbdata->set_lost_state(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -27,6 +27,15 @@
|
|||||||
|
|
||||||
class Loader;
|
class Loader;
|
||||||
|
|
||||||
|
// There is a SpeedTree bug that prevents reliably deleting a
|
||||||
|
// CForestRender object, as of version 5.2. Presumably it will be
|
||||||
|
// fixed beginning in version 5.3.
|
||||||
|
#if SPEEDTREE_VERSION_MAJOR > 5 || (SPEEDTREE_VERSION_MAJOR == 5 && SPEEDTREE_VERSION_MINOR >= 3)
|
||||||
|
#undef ST_DELETE_FOREST_HACK
|
||||||
|
#else
|
||||||
|
#define ST_DELETE_FOREST_HACK
|
||||||
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : SpeedTreeNode
|
// Class : SpeedTreeNode
|
||||||
// Description : Interfaces with the SpeedTree library to render
|
// Description : Interfaces with the SpeedTree library to render
|
||||||
@ -68,6 +77,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
SpeedTreeNode(const string &name);
|
SpeedTreeNode(const string &name);
|
||||||
|
virtual ~SpeedTreeNode();
|
||||||
|
|
||||||
INLINE bool is_valid() const;
|
INLINE bool is_valid() const;
|
||||||
|
|
||||||
@ -162,7 +172,11 @@ private:
|
|||||||
typedef ov_set<InstanceList *, IndirectLess<InstanceList> > Trees;
|
typedef ov_set<InstanceList *, IndirectLess<InstanceList> > Trees;
|
||||||
Trees _trees;
|
Trees _trees;
|
||||||
|
|
||||||
SpeedTree::CForestRender &_forest; // Hack!
|
#ifdef ST_DELETE_FOREST_HACK
|
||||||
|
SpeedTree::CForestRender &_forest;
|
||||||
|
#else
|
||||||
|
SpeedTree::CForestRender _forest;
|
||||||
|
#endif // ST_DELETE_FOREST_HACK
|
||||||
SpeedTree::CView _view;
|
SpeedTree::CView _view;
|
||||||
SpeedTree::SForestCullResultsRender _visible_trees;
|
SpeedTree::SForestCullResultsRender _visible_trees;
|
||||||
SpeedTree::CForest::SPopulationStats _population_stats;
|
SpeedTree::CForest::SPopulationStats _population_stats;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user