Introduced 'multidraw' geometry that can extend across multiple depth

intervals. This is currently used to prevent clipping of sensor geometry, but
is a more generally useful feature.
sensor-dev
Chris Laurel 2010-12-03 02:07:08 +00:00
parent bff08a31dc
commit b286ad7274
4 changed files with 83 additions and 37 deletions

View File

@ -53,6 +53,18 @@ public:
virtual void loadTextures()
{
}
/*! Return true if the geometry can be drawn multiple times in
* different depth ranges to avoid clipping and precision problems.
* Drawing multiple times is expensive, so this method should only
* return true for geometries that are simple and which need to
* be drawn correctly when the camera is positioned very close
* (relative to the size of the object.)
*/
virtual bool isMultidraw() const
{
return false;
}
};
#endif // _CELENGINE_GEOMETRY_H_

View File

@ -2848,6 +2848,7 @@ void Renderer::draw(const Observer& observer,
// large enough to have discernible surface detail are also placed in
// renderList.
renderList.clear();
multidrawRenderList.clear();
orbitPathList.clear();
lightSourceList.clear();
secondaryIlluminators.clear();
@ -3464,10 +3465,34 @@ void Renderer::draw(const Observer& observer,
nearZ = -nearZ * (float) cos(degToRad(fov / 2)) *
((float) windowHeight / maxSpan);
#endif
// Handle multidraw items; these are placed into a separate list. Items in the multidraw
// list may be drawn in multiple depth intervals.
bool isMultidraw = false;
if (iter->renderableType == RenderListEntry::RenderableBody && iter->body->getGeometry() != InvalidResource)
{
Geometry* geom = GetGeometryManager()->find(iter->body->getGeometry());
if (geom && geom->isMultidraw())
{
isMultidraw = true;
}
}
if (nearZ > -MinNearPlaneDistance)
iter->nearZ = -max(MinNearPlaneDistance, radius / 2000.0f);
{
if (isMultidraw)
{
// No contraints on far/near ratio for multidraw items
iter->nearZ = -MinNearPlaneDistance;
}
else
{
iter->nearZ = -max(MinNearPlaneDistance, radius / 2000.0f);
}
}
else
{
iter->nearZ = nearZ;
}
if (!convex)
{
@ -3509,8 +3534,15 @@ void Renderer::draw(const Observer& observer,
}
}
*notCulled = *iter;
notCulled++;
if (isMultidraw)
{
multidrawRenderList.push_back(*iter);
}
else
{
*notCulled = *iter;
notCulled++;
}
#ifdef USE_HDR
if (iter->discSizeInPixels > 1.0f &&
iter->appMag < starMaxMag)
@ -3689,8 +3721,10 @@ void Renderer::draw(const Observer& observer,
if (zNearest == prevNear)
zNearest = 0.0f;
// Add one last interval for the span from 0 to the front of the
// nearest object
// Add intervals for the span from 0 to the front of the
// nearest object. Keep the far/near ratios of the intervals
// reasonable so that we don't end up with depth buffer precision
// problems when rendering multidraw items.
{
// TODO: closest object may not be at entry 0, since objects are
// sorted by far distance.
@ -3708,13 +3742,19 @@ void Renderer::draw(const Observer& observer,
}
}
DepthBufferPartition partition;
partition.index = nIntervals;
partition.nearZ = closest;
partition.farZ = prevNear;
depthPartitions.push_back(partition);
while (prevNear < closest)
{
float n = std::min(closest, prevNear / 2000.0f);
nIntervals++;
DepthBufferPartition partition;
partition.index = nIntervals;
partition.nearZ = n;
partition.farZ = prevNear;
depthPartitions.push_back(partition);
nIntervals++;
prevNear = n;
}
}
// If orbits are enabled, adjust the farthest partition so that it
@ -3816,6 +3856,20 @@ void Renderer::draw(const Observer& observer,
i--;
}
// Render all multidraw items
for (unsigned int j = 0; j < multidrawRenderList.size(); ++j)
{
const RenderListEntry& rle = multidrawRenderList[j];
if (rle.discSizeInPixels > 1.0f && rle.farZ < depthPartitions[interval].nearZ && rle.nearZ > depthPartitions[interval].farZ)
{
//if (nearPlaneDistance * 1000000 > farPlaneDistance)
{
renderItem(rle, observer, m_cameraOrientation, nearPlaneDistance, farPlaneDistance);
}
}
}
// Render orbit paths
if (!orbitPathList.empty())
{

View File

@ -653,6 +653,7 @@ class Renderer
PointStarVertexBuffer* pointStarVertexBuffer;
PointStarVertexBuffer* glareVertexBuffer;
std::vector<RenderListEntry> renderList;
std::vector<RenderListEntry> multidrawRenderList;
std::vector<SecondaryIlluminator> secondaryIlluminators;
std::vector<DepthBufferPartition> depthPartitions;
std::vector<Particle> glareParticles;
@ -683,32 +684,6 @@ class Renderer
int currentIntervalIndex;
public:
#if 0
struct OrbitSample
{
double t;
Point3d pos;
OrbitSample(const Eigen::Vector3d& _pos, double _t) : t(_t), pos(_pos.x(), _pos.y(), _pos.z()) { }
OrbitSample() { }
};
struct OrbitSection
{
Capsuled boundingVolume;
uint32 firstSample;
};
struct CachedOrbit
{
std::vector<OrbitSample> trajectory;
std::vector<OrbitSection> sections;
uint32 lastUsed;
};
#endif
private:
typedef std::map<const Orbit*, CurvePlot*> OrbitCache;
OrbitCache orbitCache;

View File

@ -37,6 +37,11 @@ class SensorGeometry : public Geometry
virtual bool isOpaque() const;
virtual bool isNormalized() const;
virtual bool isMultidraw() const
{
return true;
}
Body* observer() const
{
return m_observer;