My mesh loader sorts the model's triangles (ie vertex indices) into attribute groups by material, that's why you'll see references to "Sorted Indices" in my sourcecode.
I'm happy to completely forget about tracking materials at this stage because I know that I can easily determine what material any triangle uses via my 'attribute lists'.
These are simply the starting index and number of indices for each group of triangles.... very similar to what we'd find in a mesh that was sourced from a ".X-File" ...
So given any triangle index, I can determine what attribute range it falls into, and that tells me what indexed material from the mesh is being applied.
And it gets even better.
The triangle indices began life as a sorted list, and are processed in order during tree generation.
They remain sorted by material at all times, hah.
[subheading]Gathering the Renderables[/subheading]
Now about Rendering.
The 'render' function won't actually draw anything - not immediately anyway... it will recurse the visible portals with an ever-shrinking frustum, gathering up the visible triangle indices into an output indexbuffer, and then drawing them, hopefully with as few as one batch involved.
[subheading]What now?[/subheading]
Of course, that's a way off yet - we need to find the Portals now, and to do that, we need to start by creating 'big fat quads' that are aligned with each splitting plane (we recorded those at each non-leaf node). The vertices of these quads lay at the intersections of the plane and the node's boundingbox. For each non leaf node, we must find four vertices which are simultaneously coplanar with (ie 'on') the splitting plane, and on the surface of the bounding box.. sounds tricky, but it's not too bad.
When we apply the 'portal rendering algorithm' which involves finding the piece of frustum sticking through visible portals, and then using that for visibility testing in the adjacent subspace, we are indeed performing occlusion culling
Remember that our triangles don't have a back face - a backfacing triangle is in another subspace. All the triangles in the same subspace are pointing toward each other and are part of its convex hull. Its how we we grouped them - if they are all pointing toward each other, then they are all on the front side of each other, and there is no plane we could choose that would divide them, proof that they are a convex set
For a given node, and with a given input frustum, we can see a given set of triangles, since its convex... by definition, occlusion cannot exist in a convex space, with the exception of planar self intersecting geometry which is something no decent artist would produce and we can with some more work detect.
If you were to create a deliberate occlusion in the same subspace as the camera, the subspace would no longer be convex, and you would have to re-process that part of the bsp tree since the affected leaves are in fact no longer leaves at all. The cost of doing so is trivial if we kept the rest of the tree intact.
So for example, if we are in a square room, which is a convex subspace, and we put a square pillar in the middle of that room, we have now made that room to be no longer convex: we can expect that room will be divided into four convex subspaces, whose shapes will depend on both input shapes.
That's an important and powerful concept which I intend to revisit. We can actually perform geometric logical operations like intersection, union/addition and difference/subtraction with pairs of meshes that have been turned into a BSP tree !!! This technique is known as Constructive Solid Geometry In the first person shooter big name corporate world, such a BSP-prepared mesh object is called a "Brush"... and you can perform operations with pairs of brushes. One of the brushes can be the entire world
Our camera's origin is a point, and a point has no volume.
The camera can exist in exactly one leaf node at a time
The BSP Tree does not tolerate occlusions - its one thing that it solves particularly well, with the exception of obviously deviant geometry such as self intersecting geometry and triangles which are extremely narrow and very similar to a line segment or edge.
The Portal Rendering algorithm is just an extension of the frustum culling algorithm, it's not magical, but it has more depth or resolution because we are recursively querying the visibility of the stuff that is definitely inside the view frustum if we can see a hole in it, STARTING from the point of view of our camera.