帧渲染系统从
NiRenderFrame开始
NiRenderFrame::Draw()开始了一帧的渲染。理论上应该一个NiRenderFrame就够了。应该是用不到多个的。
Draw开始NiRenderFrame会调用注册过的渲染前回调函数。
m_pfnPreProcessingCallback(this, m_pvPreProcessingCallbackData)回调给应用程序做处理.
NiRenderFrame会判断自己是否是需要使用Beigin EndFrame这种的结构。
如果是那么会调用
NiRenderFrame::BeginFrame NiRenderFrame::EndFrame 这样的2个函数。他里面其实就是调用D3D的begin();
然后NiRenderFrame保存的NiRenderStep数组取出来
如果这个Step是激活的就会去调用Step的Render
在Step里面一样最开始会根据是否注册过回调来回调给应用程序。
然后Step会把自己有保存的RenderClick取出来调用
RenderClicks
每一个RenderClick依然要经过严格考验。首先是要激活过的。同时要通过NiRenderClickValidator验证确实是这个Frame需要渲染的才会去渲染。
测试通过的会去调用
NiRenderClick::Render()
NiRenderClick里面依然是先回调。
然后会判断是否有渲染对象。如果没有指定渲染对象会使用默认渲染对象。
接着click会根据当前的NiRenderer渲染目标和click的渲染目标是否一致。
如果一样的那么会把当前的背景颜色设置为Renderer色。同时按照click标志为来决定是否要clearbuffer一次.
然后会判断是否有NiRenderListProcessor如果没有会使用默认的。
接着把Click里面保存的RenderView取出来按照
按照这个click的viewport来设置了创建和初始化相机。
NiRenderView里面有一个iFrameID是用来负责判断是否是同一帧调用的更新所有可见物体。如果是同一帧那么只会更新一次。不会重复更新。
Ni3DRenderView:: CalculatePVGeometry
会负责删除看不到的物体.
他内部调用NiCullingProcess来从场景根节点开始剔除所有不可能见的。
如果设置过SetAppCulled那么不管是否可见的Object都会强制被剔除。
剔除现在就是通用的。判断包围盒是否在视锥里面。如果在视锥里面会去调用对象的 Object::OnVisible(*this);
地形也作为一个Object。地形的根节点会先判断是否在视锥里面。
如果在了
然后会沿着树根节点开始向下查找。首先判断LOD层次。看着层节点的LOD是否在所允许的最小层次之上。如果不是那么就不显示了。
地形会保存一个变化到Sector空间的摄像机。然后根据设置的模式求出一个距离。
3D模式下这个距离是 相机和当前节点包围和中心位置的长度。
2.5D模式下:直接判断 相机坐标的Z值平方是否大于最大距离的平方.
2D 模式下:是 摄像机和和节点包围盒本地中心坐标的xy距离。
有个疑问这样要是在摄像机后面的地形不是应该也也符合小于最大距离?那不是后面应该看不到的也看到了??
如果距离减去当前cell的大小的距离小于最大可视距离那么这个cell可见。
加入到NiVisibleArray.
如果是可见的cell地形会调用NiTerrainCell::ProcessBorders()去处理边缘。因为有了很多lod所以去缝合等等了。
剪切完后就使用。NiCullingProcess调用preprocess
然后就是渲染所有可见的。
然后调用NiCullingProcess 调用PostProcess.