Exemplo n.º 1
0
uint32 UTransform::isOpaque()
{
	CTransform	*object = getObjectPtr();
	return object->isOpaque();
}
Exemplo n.º 2
0
// ***************************************************************************
void		CRenderTrav::traverse(UScene::TRenderPart renderPart, bool newRender)
{
#ifdef NL_DEBUG_RENDER_TRAV
    nlwarning("Render trave begin");
#endif
    H_AUTO( NL3D_TravRender );
    if (getDriver()->isLost()) return; // device is lost so no need to render anything
    CTravCameraScene::update();
    // Bind to Driver.
    setupDriverCamera();
    getDriver()->setupViewport(_Viewport);

    // reset the light setup, and set global ambient.
    resetLightSetup();
    if (newRender)
    {

        // reset the Skin manager, if needed
        if(_MeshSkinManager)
        {
            if(Driver!=_MeshSkinManager->getDriver())
            {
                _MeshSkinManager->release();
                _MeshSkinManager->init(Driver,
                                       NL3D_MESH_SKIN_MANAGER_VERTEXFORMAT,
                                       NL3D_MESH_SKIN_MANAGER_MAXVERTICES,
                                       NL3D_MESH_SKIN_MANAGER_NUMVB,
                                       "MRMSkinVB", true);
            }
        }

        // Same For Shadow ones. NB: use AuxDriver here!!!
        if(_ShadowMeshSkinManager)
        {
            if(getAuxDriver()!=_ShadowMeshSkinManager->getDriver())
            {
                _ShadowMeshSkinManager->release();
                _ShadowMeshSkinManager->init(getAuxDriver(),
                                             NL3D_SHADOW_MESH_SKIN_MANAGER_VERTEXFORMAT,
                                             NL3D_SHADOW_MESH_SKIN_MANAGER_MAXVERTICES,
                                             NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB,
                                             "ShadowSkinVB", true);
            }
        }


        // Fill OT with models, for both Opaque and transparent pass
        // =============================

        // Sort the models by distance from camera
        // This is done here and not in the addRenderModel because of the LoadBalancing traversal which can modify
        // the transparency flag (multi lod for instance)

        // clear the OTs, and prepare to allocate max element space
        OrderOpaqueList.reset(_CurrentNumVisibleModels);
        for(uint k = 0; k <= (uint) _MaxTransparencyPriority; ++k)
        {
            _OrderTransparentListByPriority[k].reset(_CurrentNumVisibleModels);	// all table share the same allocator (CLayeredOrderingTable::shareAllocator has been called)
            // and an object can be only inserted in one table, so we only need to init the main allocator
        }

        // fill the OTs.
        CTransform			**itRdrModel= NULL;
        uint32				nNbModels = _CurrentNumVisibleModels;
        if(nNbModels)
            itRdrModel= &RenderList[0];
        float	rPseudoZ, rPseudoZ2;

        // Some precalc
        float	OOFar= 1.0f / this->Far;
        uint32	opaqueOtSize= OrderOpaqueList.getSize();
        uint32	opaqueOtMax= OrderOpaqueList.getSize()-1;
        uint32	transparentOtSize= _OrderTransparentListByPriority[0].getSize(); // there is at least one list, and all list have the same number of entries
        uint32	transparentOtMax= _OrderTransparentListByPriority[0].getSize()-1;
        uint32	otId;
        // fast floor
        NLMISC::OptFastFloorBegin();
        // For all rdr models
        for( ; nNbModels>0; itRdrModel++, nNbModels-- )
        {
            CTransform			*pTransform = *itRdrModel;

            // if this entry was killed by removeRenderModel(), skip!
            if(!pTransform)
                continue;

            // Yoyo: skins are rendered through skeletons, so models WorldMatrix are all good here (even sticked objects)
            rPseudoZ = (pTransform->getWorldMatrix().getPos() - CamPos).norm();

            // rPseudoZ from 0.0 -> 1.0
            rPseudoZ =  sqrtf( rPseudoZ * OOFar );

            if( pTransform->isOpaque() )
            {
                // since norm, we are sure that rPseudoZ>=0
                rPseudoZ2 = rPseudoZ * opaqueOtSize;
                otId= NLMISC::OptFastFloor(rPseudoZ2);
                otId= min(otId, opaqueOtMax);
                OrderOpaqueList.insert( otId, pTransform );
            }
            if( pTransform->isTransparent() )
            {
                // since norm, we are sure that rPseudoZ>=0
                rPseudoZ2 = rPseudoZ * transparentOtSize;
                otId= NLMISC::OptFastFloor(rPseudoZ2);
                otId= min(otId, transparentOtMax);
                // must invert id, because transparent, sort from back to front
                _OrderTransparentListByPriority[std::min(pTransform->getTransparencyPriority(), _MaxTransparencyPriority)].insert( pTransform->getOrderingLayer(), pTransform, transparentOtMax-otId );
            }

        }
        // fast floor
        NLMISC::OptFastFloorEnd();
    }

    if (renderPart & UScene::RenderOpaque)
    {
        // Render Opaque stuff.
        // =============================

        // TestYoyo
        //OrderOpaqueList.reset(0);
        //OrderTransparentList.reset(0);

        // Clear any landscape
        clearRenderLandscapeList();

        // Start LodCharacter Manager render.
        CLodCharacterManager	*clodMngr= Scene->getLodCharacterManager();
        if(clodMngr)
            clodMngr->beginRender(getDriver(), CamPos);

        // Render the opaque materials
        _CurrentPassOpaque = true;
        OrderOpaqueList.begin();
        while( OrderOpaqueList.get() != NULL )
        {
            CTransform	*tr= OrderOpaqueList.get();
#ifdef NL_DEBUG_RENDER_TRAV
            CTransformShape *trShape = dynamic_cast<CTransformShape *>(tr);
            if (trShape)
            {
                const std::string *shapeName = Scene->getShapeBank()->getShapeNameFromShapePtr(trShape->Shape);
                if (shapeName)
                {
                    nlwarning("Displaying %s", shapeName->c_str());
                }
            }
#endif
            tr->traverseRender();
            OrderOpaqueList.next();
        }

        /* Render MeshBlock Manager.
        	Some Meshs may be render per block. Interesting to remove VertexBuffer and Material setup overhead.
        	Faster if rendered before lods, for ZBuffer optimisation: render first near objects then far.
        	Lods are usually far objects.
        */
        MeshBlockManager.flush(Driver, Scene, this);


        // End LodCharacter Manager render.
        if(clodMngr)
            clodMngr->endRender();


        /* Render Scene CoarseMeshManager.
        	Important to render them at end of Opaque rendering, because coarses instances are created/removed during
        	this model opaque rendering pass.
        */
        if( Scene->getCoarseMeshManager() )
            Scene->getCoarseMeshManager()->flushRender(Driver);

        /* Render ShadowMaps.
        	Important to render them at end of Opaque rendering, because alphaBlended objects must blend with opaque
        	objects shadowed.
        	Therefore, transparent objects neither can't cast or receive shadows...

        	NB: Split in 2 calls and interleave Landscape Rendering between the 2. WHY???
        	Because it is far more efficient for VBLock (but not for ZBuffer optim...) because in renderGenerate()
        	the ShadowMeshSkinManager do lot of VBLocks that really stall (because only 2 VBHard with swap scheme).

        	Therefore the first Lock that stall will wait not only for the first MeshSkin to finish but also for the
        	preceding landscape render to finish too! => big STALL.
        */

        // Generate ShadowMaps
        _ShadowMapManager.renderGenerate(Scene);

        // Render the Landscape
        renderLandscapes();

        // Project ShadowMaps.
        if(Scene->getLandscapePolyDrawingCallback() != NULL)
        {
            Scene->getLandscapePolyDrawingCallback()->beginPolyDrawing();
        }
        _ShadowMapManager.renderProject(Scene);
        if(Scene->getLandscapePolyDrawingCallback())
        {
            Scene->getLandscapePolyDrawingCallback()->endPolyDrawing();
        }

        // Profile this frame?
        if(Scene->isNextRenderProfile())
        {
            OrderOpaqueList.begin();
            while( OrderOpaqueList.get() != NULL )
            {
                OrderOpaqueList.get()->profileRender();
                OrderOpaqueList.next();
            }
        }
    }


    if (renderPart & UScene::RenderTransparent)
    {
        if (_FirstWaterModel) // avoid a lock if no water is to be rendered
        {
            // setup water models
            CWaterModel *curr = _FirstWaterModel;
            uint numWantedVertices = 0;
            while (curr)
            {
                numWantedVertices += curr->getNumWantedVertices();
                curr = curr->_Next;
            }
            if (numWantedVertices != 0)
            {
                CWaterModel::setupVertexBuffer(Scene->getWaterVB(), numWantedVertices, getDriver());
                //
                {
                    CVertexBufferReadWrite vbrw;
                    Scene->getWaterVB().lock(vbrw);
                    CWaterModel *curr = _FirstWaterModel;
                    void *datas = vbrw.getVertexCoordPointer(0);
                    //
                    uint tri = 0;
                    while (curr)
                    {
                        tri = curr->fillVB(datas, tri, *getDriver());
                        nlassert(tri <= numWantedVertices);
                        curr = curr->_Next;
                    }
                    nlassert(tri * 3 == numWantedVertices);
                }
            }
            // Unlink all water model
            clearWaterModelList();
        }
    }

    if ((renderPart & UScene::RenderTransparent) &&
            (renderPart & UScene::RenderFlare)
       )
    {
        // Render all transparent stuffs including flares.
        // =============================
        // Render transparent materials (draw higher priority last, because their appear in front)
        _CurrentPassOpaque = false;
        for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
        {
            it->begin(_LayersRenderingOrder);
            while( it->get() != NULL )
            {
#ifdef NL_DEBUG_RENDER_TRAV
                CTransformShape *trShape = dynamic_cast<CTransformShape *>(it->get());
                if (trShape)
                {
                    const std::string *shapeName = Scene->getShapeBank()->getShapeNameFromShapePtr(trShape->Shape);
                    if (shapeName)
                    {
                        nlwarning("Displaying %s", shapeName->c_str());
                    }
                }
#endif
                it->get()->traverseRender();
                it->next();
            }
        }

        // Profile this frame?
        if(Scene->isNextRenderProfile())
        {
            for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
            {
                it->begin();
                while( it->get() != NULL )
                {
                    it->get()->profileRender();
                    it->next();
                }
            }
        }
    }
    else if (renderPart & UScene::RenderTransparent)
    {
        // Render all transparent stuffs, don't render flares
        // =============================
        _CurrentPassOpaque = false;
        for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
        {
            it->begin(_LayersRenderingOrder);
            while( it->get() != NULL )
            {
                if (!it->get()->isFlare())
                {
#ifdef NL_DEBUG_RENDER_TRAV
                    CTransformShape *trShape = dynamic_cast<CTransformShape *>(it->get());
                    if (trShape)
                    {
                        const std::string *shapeName = Scene->getShapeBank()->getShapeNameFromShapePtr(trShape->Shape);
                        if (shapeName)
                        {
                            nlwarning("Displaying %s", shapeName->c_str());
                        }
                    }
#endif
                    it->get()->traverseRender();
                }
                it->next();
            }
        }

        // Profile this frame?
        if(Scene->isNextRenderProfile())
        {
            for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
            {
                it->begin();
                while( it->get() != NULL )
                {
                    if (!it->get()->isFlare())
                    {
                        it->get()->profileRender();
                    }
                    it->next();
                }
            }
        }
    }
    else if (renderPart & UScene::RenderFlare)
    {
        // Render flares only
        // =============================
        _CurrentPassOpaque = false;
        for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
        {
            it->begin(_LayersRenderingOrder);
            while( it->get() != NULL )
            {
                if (it->get()->isFlare())
                {
#ifdef NL_DEBUG_RENDER_TRAV
                    CTransformShape *trShape = dynamic_cast<CTransformShape *>(it->get());
                    if (trShape)
                    {
                        const std::string *shapeName = Scene->getShapeBank()->getShapeNameFromShapePtr(trShape->Shape);
                        if (shapeName)
                        {
                            nlwarning("Displaying %s", shapeName->c_str());
                        }
                    }
#endif
                    it->get()->traverseRender();
                }
                it->next();
            }
        }

        // Profile this frame?
        if(Scene->isNextRenderProfile())
        {
            for(std::vector<CLayeredOrderingTable<CTransform> >::iterator it = _OrderTransparentListByPriority.begin(); it != _OrderTransparentListByPriority.end(); ++it)
            {
                it->begin();
                while( it->get() != NULL )
                {
                    if (it->get()->isFlare())
                    {
                        it->get()->profileRender();
                    }
                    it->next();
                }
            }
        }
    }

    // END!
    // =============================

    // clean: reset the light setup
    resetLightSetup();

}