Ticket #2431: patch_optimization.patch

File patch_optimization.patch, 9.9 KB (added by Lucas Malo Bélanger, 10 years ago)

Gameview optimization

  • source/graphics/Frustum.cpp

     
    185185    return true;
    186186}
    187187
     188bool CFrustum::operator==(const CFrustum& other) const
     189{
     190    for(ssize_t i = 0; i < MAX_NUM_FRUSTUM_PLANES; i++)
     191    {
     192        if(m_aPlanes[i] != other.m_aPlanes[i])
     193            return false;
     194    }
     195    return true;
     196}
    188197
     198bool CFrustum::operator!=(const CFrustum& other) const
     199{
     200    for(ssize_t i = 0; i < MAX_NUM_FRUSTUM_PLANES; i++)
     201    {
     202        if(m_aPlanes[i] != other.m_aPlanes[i])
     203            return true;
     204    }
     205    return false;
     206}
     207
     208
  • source/graphics/Frustum.h

     
    6060    CPlane& operator[](size_t idx) { return m_aPlanes[idx]; }
    6161    const CPlane& operator[](size_t idx) const { return m_aPlanes[idx]; }
    6262
     63    bool operator==(const CFrustum& other) const;
     64    bool operator!=(const CFrustum& other) const;
    6365public:
    6466    //make the planes public for ease of use
    6567    CPlane m_aPlanes[MAX_NUM_FRUSTUM_PLANES];
  • source/graphics/GameView.cpp

     
    1515 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
    1616 */
    1717
     18#include <algorithm>
     19#include <vector>
     20#include <iterator>
     21
    1822#include "precompiled.h"
    1923
    2024#include "GameView.h"
     
    351355    orientation->Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue());
    352356}
    353357
     358//only internal use for std::generate
     359class CoordsGenerator
     360{
     361public:
     362    CoordsGenerator(const ssize_t& num_patches);
     363    ~CoordsGenerator(){}
     364
     365    std::pair<ssize_t,ssize_t> operator()();
     366private:
     367    ssize_t x_;
     368    ssize_t y_;
     369    const ssize_t& num_patches_;
     370};
     371
     372CoordsGenerator::CoordsGenerator(const ssize_t& num_patches):
     373    num_patches_(num_patches),x_(0),y_(0)
     374{
     375}
     376
     377std::pair<ssize_t,ssize_t> CoordsGenerator::operator()()
     378{
     379    std::pair<ssize_t,ssize_t> res;
     380    res.first = x_;
     381    res.second = y_;
     382
     383    x_++;
     384    if(x_ >= num_patches_)
     385    {
     386        x_ = 0;
     387        y_++;
     388    }
     389    return res;
     390}
     391
    354392CGameView::CGameView(CGame *pGame):
    355393    m(new CGameViewImpl(pGame))
    356394{
     
    501539///////////////////////////////////////////////////////////
    502540// This callback is part of the Scene interface
    503541// Submit all objects visible in the given frustum
     542
    504543void CGameView::EnumerateObjects(const CFrustum& frustum, SceneCollector* c)
    505544{
    506545    {
    507546    PROFILE3("submit terrain");
    508547
    509     CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
    510     const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide();
     548    static CTerrain* pTerrain = 0;
    511549
    512     // find out which patches will be drawn
    513     for (ssize_t j=0; j<patchesPerSide; j++) {
    514         for (ssize_t i=0; i<patchesPerSide; i++) {
    515             CPatch* patch=pTerrain->GetPatch(i,j);  // can't fail
     550    float waterHeight = 0.0f;
     551    CPatch* patch = 0;
     552    const CVector3D zero = CVector3D(0,0,0);
    516553
    517             // If the patch is underwater, calculate a bounding box that also contains the water plane
     554    static std::vector<std::pair<ssize_t,ssize_t> > coords;
     555   
     556    //checking if terrain pointer needs to get updated
     557    //if so, update also the patch coordinates
     558    if(pTerrain != m->Game->GetWorld()->GetTerrain())
     559    {
     560        pTerrain = m->Game->GetWorld()->GetTerrain();
     561        const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide();
     562        coords.clear();
     563        coords.resize(patchesPerSide*patchesPerSide);
     564        CoordsGenerator gen(patchesPerSide);
     565        std::generate(coords.begin(),coords.end(),gen);
     566    }
     567
     568    static std::vector<CPatch*> patches_to_draw;
     569    static CFrustum lastView = CFrustum();
     570    std::vector<CPatch*>::iterator patch_iterator;
     571    std::vector<std::pair<ssize_t,ssize_t> >::iterator coord;
     572    ssize_t x;
     573    ssize_t y;
     574
     575    //checking if current view is the same than last frame
     576    //if not, update the patches to draw
     577    if(lastView != frustum)
     578    {
     579        lastView = frustum;
     580        std::vector<CPatch*>::iterator it;
     581
     582        //deactivating last patches
     583        while(patches_to_draw.size() != 0)
     584        {
     585            it = patches_to_draw.end() - 1;
     586            if((*it) != NULL)
     587                (*it)->setDrawState(false);
     588            patches_to_draw.pop_back();
     589        }
     590        patches_to_draw.reserve(pTerrain->GetPatchesPerSide()*pTerrain->GetPatchesPerSide());
     591
     592        //deciding which patches to draw
     593        for(coord = coords.begin(); coord < coords.end(); coord++)
     594        {
     595            x = coord->first;
     596            y = coord->second;
     597
     598            patch = pTerrain->GetPatch(x,y);
    518599            CBoundingBoxAligned bounds = patch->GetWorldBounds();
    519             float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f;
    520             if(bounds[1].Y < waterHeight) {
    521                 bounds[1].Y = waterHeight;
    522             }
     600            waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f;
     601            bounds[1].Y = waterHeight*(bounds[1].Y >= waterHeight) + bounds[1].Y*(bounds[1].Y < waterHeight);
    523602
    524             if (!m->Culling || frustum.IsBoxVisible (CVector3D(0,0,0), bounds)) {
    525                 //c->Submit(patch);
     603            if (!m->Culling || frustum.IsBoxVisible (zero, bounds)) {
    526604
    527605                // set the renderstate for this patch
    528                 patch->setDrawState(true);
     606                patches_to_draw.push_back(patch);
    529607
    530608                // set the renderstate for the neighbors
    531609                CPatch *nPatch;
    532610
    533                 nPatch = pTerrain->GetPatch(i-1,j-1);
    534                 if(nPatch) nPatch->setDrawState(true);
     611                nPatch = pTerrain->GetPatch(x-1,y-1);
     612                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     613                if(nPatch && patch_iterator == patches_to_draw.end())
     614                {
     615                    patches_to_draw.push_back(nPatch);
     616                    nPatch->setDrawState(true);
     617                }
    535618
    536                 nPatch = pTerrain->GetPatch(i,j-1);
    537                 if(nPatch) nPatch->setDrawState(true);
     619                nPatch = pTerrain->GetPatch(x,y-1);
     620                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     621                if(nPatch && patch_iterator == patches_to_draw.end())
     622                {
     623                    patches_to_draw.push_back(nPatch);
     624                    nPatch->setDrawState(true);
     625                }
    538626
    539                 nPatch = pTerrain->GetPatch(i+1,j-1);
    540                 if(nPatch) nPatch->setDrawState(true);
     627                nPatch = pTerrain->GetPatch(x+1,y-1);
     628                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     629                if(nPatch && patch_iterator == patches_to_draw.end())
     630                {
     631                    patches_to_draw.push_back(nPatch);
     632                    nPatch->setDrawState(true);
     633                }
    541634
    542                 nPatch = pTerrain->GetPatch(i-1,j);
    543                 if(nPatch) nPatch->setDrawState(true);
     635                nPatch = pTerrain->GetPatch(x-1,y);
     636                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     637                if(nPatch && patch_iterator == patches_to_draw.end())
     638                {
     639                    patches_to_draw.push_back(nPatch);
     640                    nPatch->setDrawState(true);
     641                }
    544642
    545                 nPatch = pTerrain->GetPatch(i+1,j);
    546                 if(nPatch) nPatch->setDrawState(true);
     643                nPatch = pTerrain->GetPatch(x+1,y);
     644                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     645                if(nPatch && patch_iterator == patches_to_draw.end())
     646                {
     647                    patches_to_draw.push_back(nPatch);
     648                    nPatch->setDrawState(true);
     649                }
    547650
    548                 nPatch = pTerrain->GetPatch(i-1,j+1);
    549                 if(nPatch) nPatch->setDrawState(true);
     651                nPatch = pTerrain->GetPatch(x-1,y+1);
     652                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     653                if(nPatch && patch_iterator == patches_to_draw.end())
     654                {
     655                    patches_to_draw.push_back(nPatch);
     656                    nPatch->setDrawState(true);
     657                }
    550658
    551                 nPatch = pTerrain->GetPatch(i,j+1);
    552                 if(nPatch) nPatch->setDrawState(true);
     659                nPatch = pTerrain->GetPatch(x,y+1);
     660                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     661                if(nPatch && patch_iterator == patches_to_draw.end())
     662                {
     663                    patches_to_draw.push_back(nPatch);
     664                    nPatch->setDrawState(true);
     665                }
    553666
    554                 nPatch = pTerrain->GetPatch(i+1,j+1);
    555                 if(nPatch) nPatch->setDrawState(true);
     667                nPatch = pTerrain->GetPatch(x+1,y+1);
     668                patch_iterator = std::find(patches_to_draw.begin(),patches_to_draw.end(),nPatch);
     669                if(nPatch && patch_iterator == patches_to_draw.end())
     670                {
     671                    patches_to_draw.push_back(nPatch);
     672                    nPatch->setDrawState(true);
     673                }
    556674            }
    557675        }
    558676    }
     677   
     678    //submit the patches that are activated
     679    for(patch_iterator = patches_to_draw.begin();patch_iterator < patches_to_draw.end();patch_iterator++)
     680        c->Submit(*patch_iterator);
    559681
    560     // draw the patches
    561     for (ssize_t j=0; j<patchesPerSide; j++)
    562     {
    563         for (ssize_t i=0; i<patchesPerSide; i++)
    564         {
    565             CPatch* patch=pTerrain->GetPatch(i,j);  // can't fail
    566             if(patch->getDrawState() == true)
    567             {
    568                 c->Submit(patch);
    569                 patch->setDrawState(false);
    570             }
    571         }
     682    m->Game->GetSimulation2()->RenderSubmit(*c, frustum, m->Culling);
    572683    }
    573     }
    574 
    575     m->Game->GetSimulation2()->RenderSubmit(*c, frustum, m->Culling);
    576684}
    577685
    578686
     
    11641272    }
    11651273
    11661274    return IN_PASS;
    1167 }
     1275}
     1276 No newline at end of file
  • source/maths/Plane.cpp

     
    133133    *intsect = start - (direction * (DistanceToPlane (start)/dot));
    134134    return true;
    135135}
     136
     137bool CPlane::operator!=(const CPlane& other) const
     138{
     139    return m_Norm != other.m_Norm || m_Dist != other.m_Dist;
     140}
     141
     142bool CPlane::operator==(const CPlane& other) const
     143{
     144    return m_Norm == other.m_Norm && m_Dist == other.m_Dist;
     145}
  • source/maths/Plane.h

     
    6363        bool FindLineSegIntersection (const CVector3D &start, const CVector3D &end, CVector3D *intsect);
    6464        bool FindRayIntersection (const CVector3D &start, const CVector3D &direction, CVector3D *intsect);
    6565
     66        bool operator!=(const CPlane& other) const;
     67        bool operator==(const CPlane& other) const;
     68
    6669    public:
    6770        CVector3D m_Norm;   //normal vector of the plane
    6871        float m_Dist;       //Plane distance (ie D in the plane eq.)