i have read some articles about portal rendering - unfortunately, it seems there are only a few on the web.
From what i have understand i have build some code.
It would be nice if someone could review my main loop for object culling / rendering.
Short description of the code: I render the current sector (the one the viewpos is in), then iterate over each portal, clip them against the current view frustum and build a reduced view frustum from those. Finally, i render the adjacent sector, which should recursively render all sectors until all visible ones are drawn.
Is this procedure correct or are there some flaws in my code?
Thanks in adavance,
Gammastrahler
void ZSector::render(const CVector3 &currPos, CFrustum &viewFrustum)
{
if (_tagged) return;
_tagged = true;
gPolysDrawn++;
// Render the current sector
std::vector<CPolygon*>::iterator pPoly = _polyList.begin();
for ( ; pPoly != _polyList.end(); ++pPoly)
{
(*pPoly)->render(currPos);
}
for (std::vector<ZPortal*>::iterator p = _portalList.begin();
p != _portalList.end(); ++p)
{
CPolygon clippedPortal = (*p)->_poly;
// If the portal is not within the current view frustum, ignore it
if (!viewFrustum.poly_visible(clippedPortal)) continue;
// Clip the portal against each plane of our view frustum
for (int plane = 0; plane < viewFrustum._nPlanes; plane++)
{
CPolygon result[2];
if (SplitPolygon(clippedPortal, viewFrustum._planes[plane], result))
clippedPortal = result[0];
}
// Check for invalid portals
if (clippedPortal._nVerts < 3) continue;
// Remember the near and far plane
CPlane farPlane = viewFrustum._planes[viewFrustum._nPlanes-2];
CPlane nearPlane = viewFrustum._planes[viewFrustum._nPlanes-1];
viewFrustum._nPlanes = 0;
// Build the reduced view frustum from the
// new portal
for (int i = 0; i < clippedPortal._nVerts; i++)
{
CVertex v1 = clippedPortal._verts;
CVertex v2 = clippedPortal._verts[i+1];
if (i == clippedPortal._nVerts - 1)
v2 = clippedPortal._verts[0];
CVector3 sideNormal;
sideNormal.Cross(v2, v1);
sideNormal.normalize();
viewFrustum._planes._normal = sideNormal;
viewFrustum._planes._d = 0.0;
viewFrustum._nPlanes++;
}
// Reset the near and far plane
viewFrustum._planes[viewFrustum._nPlanes++] = farPlane;
viewFrustum._planes[viewFrustum._nPlanes++] = nearPlane;
// Call adjacent sector
if ((*p)->_adjacent)
(*p)->_adjacent->render(currPos, viewFrustum);
}
}