This commit is contained in:
David Rose 2010-10-14 00:31:36 +00:00
parent 803ef5effd
commit f85ccdf0f3
3 changed files with 58 additions and 21 deletions

View File

@ -56,9 +56,9 @@ ConfigVariableDouble speedtree_max_anisotropy
ConfigVariableBool speedtree_horizontal_billboards
("speedtree-horizontal-billboards", true,
PRC_DESC("Set this true to allow the use of horizontal billboards in "
"SpeedTree, or false to disallow them. Documentation on this "
"feature is sparse, but presumably enabling them increases "
"visual quality and also causes a greater performance impact."));
"SpeedTree, or false to disallow them. Horizontal billboards "
"may be defined for some trees to provide a billboard LOD "
"when the tree is seen from above."));
ConfigVariableDouble speedtree_alpha_test_scalar
("speedtree-alpha-test-scalar", 0.57,

View File

@ -33,6 +33,7 @@
#include "loader.h"
#include "deg_2_rad.h"
#include "sceneGraphReducer.h"
#include "pStatTimer.h"
#ifdef SPEEDTREE_OPENGL
#include "glew/glew.h"
@ -47,6 +48,16 @@ bool SpeedTreeNode::_done_first_init;
TypeHandle SpeedTreeNode::_type_handle;
TypeHandle SpeedTreeNode::DrawCallback::_type_handle;
PStatCollector SpeedTreeNode::_cull_speedtree_pcollector("Cull:SpeedTree");
PStatCollector SpeedTreeNode::_cull_speedtree_shadows_pcollector("Cull:SpeedTree:Shadows");
PStatCollector SpeedTreeNode::_cull_speedtree_trees_pcollector("Cull:SpeedTree:Trees");
PStatCollector SpeedTreeNode::_cull_speedtree_terrain_pcollector("Cull:SpeedTree:Terrain");
PStatCollector SpeedTreeNode::_draw_speedtree_pcollector("Draw:SpeedTree");
PStatCollector SpeedTreeNode::_draw_speedtree_shadows_pcollector("Draw:SpeedTree:Shadows");
PStatCollector SpeedTreeNode::_draw_speedtree_trees_pcollector("Draw:SpeedTree:Trees");
PStatCollector SpeedTreeNode::_draw_speedtree_terrain_pcollector("Draw:SpeedTree:Terrain");
PStatCollector SpeedTreeNode::_draw_speedtree_terrain_update_pcollector("Draw:SpeedTree:Terrain:Update");
////////////////////////////////////////////////////////////////////
// Function: SpeedTreeNode::Constructor
// Access: Published
@ -873,6 +884,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
if (!_is_valid) {
return false;
}
PStatTimer timer(_cull_speedtree_pcollector);
GraphicsStateGuardian *gsg = DCAST(GraphicsStateGuardian, trav->get_gsg());
nassertr(gsg != (GraphicsStateGuardian *)NULL, true);
@ -948,6 +960,7 @@ cull_callback(CullTraverser *trav, CullTraverserData &data) {
if (dlight != (DirectionalLight *)NULL) {
CPT(TransformState) transform = dlight_np.get_transform(trav->get_scene()->get_scene_root().get_parent());
LVector3f dir = dlight->get_direction() * transform->get_mat();
dir.normalize();
_light_dir = SpeedTree::Vec3(dir[0], dir[1], dir[2]);
diffuse_color = dlight->get_color();
@ -1372,6 +1385,7 @@ validate_api(GraphicsStateGuardian *gsg) {
////////////////////////////////////////////////////////////////////
void SpeedTreeNode::
draw_callback(CallbackData *data) {
PStatTimer timer(_draw_speedtree_pcollector);
GeomDrawCallbackData *geom_cbdata;
DCAST_INTO_V(geom_cbdata, data);
@ -1389,6 +1403,7 @@ draw_callback(CallbackData *data) {
// Update the shadow maps. TODO: consider updating these only
// every once in a while, instead of every frame, as a simple
// optimization.
PStatTimer timer(_draw_speedtree_shadows_pcollector);
render_forest_into_shadow_maps();
_forest_render.ClearBoundTextures( );
}
@ -1400,6 +1415,7 @@ draw_callback(CallbackData *data) {
}
if (has_terrain()) {
PStatTimer timer1(_draw_speedtree_terrain_pcollector);
// Is this needed for terrain?
_terrain_render.UploadShaderConstants
(&_forest_render, _light_dir,
@ -1424,23 +1440,28 @@ draw_callback(CallbackData *data) {
}
}
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool fronds = _forest_render.RenderFronds(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool leaf_meshes = _forest_render.RenderLeafMeshes(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool leaf_cards = _forest_render.RenderLeafCards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
bool billboards = _forest_render.RenderBillboards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
{
// Now draw the actual trees.
PStatTimer timer1(_draw_speedtree_trees_pcollector);
if (!branches || !fronds || !leaf_meshes || !leaf_cards || !billboards) {
speedtree_cat.warning()
<< "Failed to render forest completely: "
<< branches << " " << fronds << " " << leaf_meshes << " " << leaf_cards << " " << billboards << "\n";
write_error(speedtree_cat.warning());
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TESTING;
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_ALPHA_TO_COVERAGE;
// SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_BLENDING;
SpeedTree::ETextureAlphaRenderMode mode = SpeedTree::TRANS_TEXTURE_NOTHING;
set_transparent_texture_mode(SpeedTree::ETextureAlphaRenderMode(mode));
bool branches = _forest_render.RenderBranches(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool fronds = _forest_render.RenderFronds(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool leaf_meshes = _forest_render.RenderLeafMeshes(_visible_trees, SpeedTree::RENDER_PASS_STANDARD);
bool leaf_cards = _forest_render.RenderLeafCards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
bool billboards = _forest_render.RenderBillboards(_visible_trees, SpeedTree::RENDER_PASS_STANDARD, _view);
if (!branches || !fronds || !leaf_meshes || !leaf_cards || !billboards) {
speedtree_cat.warning()
<< "Failed to render forest completely: "
<< branches << " " << fronds << " " << leaf_meshes << " " << leaf_cards << " " << billboards << "\n";
write_error(speedtree_cat.warning());
}
}
_forest_render.EndRender();
@ -1637,6 +1658,7 @@ setup_for_render(GraphicsStateGuardian *gsg) {
_needs_repopulate = false;
}
if (has_terrain()) {
PStatTimer timer1(_draw_speedtree_terrain_update_pcollector);
update_terrain_cells();
}
}
@ -1649,12 +1671,17 @@ setup_for_render(GraphicsStateGuardian *gsg) {
////////////////////////////////////////////////////////////////////
void SpeedTreeNode::
cull_forest() {
_forest_render.CullAndComputeLOD(_view, _visible_trees);
{
PStatTimer timer1(_cull_speedtree_trees_pcollector);
_forest_render.CullAndComputeLOD(_view, _visible_trees);
}
if (has_terrain()) {
PStatTimer timer1(_cull_speedtree_terrain_pcollector);
_terrain_render.CullAndComputeLOD(_view, _visible_terrain);
}
if (_forest_render.ShadowsAreEnabled()) {
PStatTimer timer1(_cull_speedtree_shadows_pcollector);
for (int smi = 0; smi < (int)_shadow_infos.size(); ++smi) {
SpeedTree::CView &light_view = _shadow_infos[smi]._light_view;
SpeedTree::SForestCullResultsRender &light_cull = _shadow_infos[smi]._light_cull;

View File

@ -25,7 +25,7 @@
#include "loaderOptions.h"
#include "transformState.h"
#include "nodePath.h"
#include "pStatCollector.h"
#include "speedtree_api.h"
class Loader;
@ -240,6 +240,16 @@ private:
static bool _authorized;
static bool _done_first_init;
static PStatCollector _cull_speedtree_pcollector;
static PStatCollector _cull_speedtree_shadows_pcollector;
static PStatCollector _cull_speedtree_trees_pcollector;
static PStatCollector _cull_speedtree_terrain_pcollector;
static PStatCollector _draw_speedtree_pcollector;
static PStatCollector _draw_speedtree_shadows_pcollector;
static PStatCollector _draw_speedtree_trees_pcollector;
static PStatCollector _draw_speedtree_terrain_pcollector;
static PStatCollector _draw_speedtree_terrain_update_pcollector;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);