Ticket #1923: minimap.2.patch

File minimap.2.patch, 8.2 KB (added by tuan kuranes, 10 years ago)

fixed fixed function renderpath

  • source/gui/MiniMap.h

     
    1919#define INCLUDED_MINIMAP
    2020
    2121#include "gui/GUI.h"
     22#include "renderer/VertexArray.h"
    2223
     24
    2325class CCamera;
    2426class CTerrain;
    2527
     
    8890    void GetMouseWorldCoordinates(float& x, float& z);
    8991
    9092    float GetAngle();
     93
     94   
     95    VertexIndexArray m_IndexArray;
     96
     97    VertexArray m_VertexArray;
     98    VertexArray::Attribute m_AttributePos;
     99    VertexArray::Attribute m_AttributeColor;
     100
     101    size_t m_UnitDrawn;
    91102};
    92103
    93104#endif
  • source/gui/MiniMap.cpp

     
    4444
    4545bool g_GameRestarted = false;
    4646
     47const u16 maxEntitiesDrawn = 8144;
     48
    4749static unsigned int ScaleColor(unsigned int color, float x)
    4850{
    4951    unsigned int r = unsigned(float(color & 0xff) * x);
     
    5355}
    5456
    5557CMiniMap::CMiniMap() :
    56     m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f)
     58    m_TerrainTexture(0), m_TerrainData(0), m_MapSize(0), m_Terrain(0), m_TerrainDirty(true), m_MapScale(1.f),
     59    m_IndexArray(GL_STATIC_DRAW),
     60    m_VertexArray(GL_DYNAMIC_DRAW)
    5761{
    5862    AddSetting(GUIST_CColor,    "fov_wedge_color");
    5963    AddSetting(GUIST_CStrW,     "tooltip");
     
    6973        m_ShallowPassageHeight = pathingSettings.GetChild("default").GetChild("MaxWaterDepth").ToFloat();
    7074    else
    7175        m_ShallowPassageHeight = 0.0f;
     76       
     77    m_AttributePos.type = GL_FLOAT;
     78    m_AttributePos.elems = 2;
     79    m_VertexArray.AddAttribute(&m_AttributePos);
     80   
     81    m_AttributeColor.type = GL_UNSIGNED_BYTE;
     82    m_AttributeColor.elems = 4;
     83    m_VertexArray.AddAttribute(&m_AttributeColor);
     84   
     85    m_VertexArray.SetNumVertices(maxEntitiesDrawn);
     86    m_VertexArray.Layout();
     87
     88    m_IndexArray.SetNumVertices(maxEntitiesDrawn);
     89    m_IndexArray.Layout();
     90    VertexArrayIterator<u16> index = m_IndexArray.GetIterator();
     91    for (u16 i = 0; i < maxEntitiesDrawn; ++i)
     92    {
     93        *index++ = i;
     94    }
     95    m_IndexArray.Upload();
     96    m_IndexArray.FreeBackingStore();
     97   
     98   
     99    VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>();
     100    VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>();
     101    for (u16 i = 0; i < maxEntitiesDrawn; i++)
     102    {
     103        (*attrColor)[0] = 0;
     104        (*attrColor)[1] = 0;
     105        (*attrColor)[2] = 0;
     106        (*attrColor)[3] = 0;
     107        ++attrColor;
     108
     109        (*attrPos)[0] = -10000.0f;
     110        (*attrPos)[1] = -10000.0f;
     111       
     112        ++attrPos;
     113       
     114    }
     115    m_VertexArray.Upload();
    72116}
    73117
    74118CMiniMap::~CMiniMap()
     
    218262    hitPt[3]=m_Camera->GetWorldCoordinates(0, 0, h);
    219263
    220264    float ViewRect[4][2];
     265    const float invTileMapSize = 1.0f/float(TERRAIN_TILE_SIZE*m_MapSize);
    221266    for (int i=0;i<4;i++) {
    222267        // convert to minimap space
    223         float px=hitPt[i].X;
    224         float pz=hitPt[i].Z;
    225         ViewRect[i][0]=(m_CachedActualSize.GetWidth()*px/float(TERRAIN_TILE_SIZE*m_MapSize));
    226         ViewRect[i][1]=(m_CachedActualSize.GetHeight()*pz/float(TERRAIN_TILE_SIZE*m_MapSize));
     268        const float px=hitPt[i].X;
     269        const float pz=hitPt[i].Z;
     270        ViewRect[i][0]=(m_CachedActualSize.GetWidth()*px*invTileMapSize);
     271        ViewRect[i][1]=(m_CachedActualSize.GetHeight()*pz*invTileMapSize);
    227272    }
    228273
    229274    // Enable Scissoring as to restrict the rectangle
     
    276321    glEnd();
    277322}
    278323
     324// TODO: render the minimap in a framebuffer
     325// and just draw the frambuffer texture most of the time
     326// updating the framebuffer twice a frame.
     327// Here it update as ping-pong either texture or vertex array
     328// each sec to lower gpu stalling
     329// (those operation cause a gpu sync, which slows down a lot
     330// the way gpu works.)
    279331void CMiniMap::Draw()
    280332{
    281333    PROFILE3("render minimap");
     
    305357    // only update 2x / second
    306358    // (note: since units only move a few pixels per second on the minimap,
    307359    // we can get away with infrequent updates; this is slow)
     360    // store frequency in a perf config file ?
    308361    static double last_time;
    309362    const double cur_time = timer_Time();
    310     if(cur_time - last_time > 0.5)
    311     {
     363    const bool doUpdate = cur_time - last_time > 0.5;
     364    if(doUpdate)
     365    {   
    312366        last_time = cur_time;
    313 
    314367        if(m_TerrainDirty)
    315368            RebuildTerrainTexture();
    316369    }
     
    444497
    445498    PROFILE_START("minimap units");
    446499
    447     // Don't enable GL_POINT_SMOOTH because it's far too slow
    448     // (~70msec/frame on a GF4 rendering a thousand points)
    449     glPointSize(3.f);
    450500
    451     float sx = (float)m_Width / ((m_MapSize - 1) * TERRAIN_TILE_SIZE);
    452     float sy = (float)m_Height / ((m_MapSize - 1) * TERRAIN_TILE_SIZE);
     501    const float sx = (float)m_Width / ((m_MapSize - 1) * TERRAIN_TILE_SIZE);
     502    const float sy = (float)m_Height / ((m_MapSize - 1) * TERRAIN_TILE_SIZE);
    453503
    454504    CSimulation2::InterfaceList ents = sim->GetEntitiesWithInterface(IID_Minimap);
    455505
    456     std::vector<MinimapUnitVertex> vertexArray;
    457     vertexArray.reserve(ents.size());
     506    if (doUpdate)
     507    {
    458508
    459     for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
    460     {
     509        VertexArrayIterator<float[2]> attrPos = m_AttributePos.GetIterator<float[2]>();
     510        VertexArrayIterator<u8[4]> attrColor = m_AttributeColor.GetIterator<u8[4]>();
     511
     512        m_UnitDrawn = 0;
    461513        MinimapUnitVertex v;
    462         ICmpMinimap* cmpMinimap = static_cast<ICmpMinimap*>(it->second);
    463514        entity_pos_t posX, posZ;
    464         if (cmpMinimap->GetRenderData(v.r, v.g, v.b, posX, posZ))
     515        for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it)
    465516        {
    466             ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(it->first, g_Game->GetPlayerID());
    467             if (vis != ICmpRangeManager::VIS_HIDDEN)
     517            ICmpMinimap* cmpMinimap = static_cast<ICmpMinimap*>(it->second);
     518            if (cmpMinimap->GetRenderData(v.r, v.g, v.b, posX, posZ))
    468519            {
    469                 v.a = 255;
    470                 v.x = posX.ToFloat()*sx;
    471                 v.y = -posZ.ToFloat()*sy;
    472                 vertexArray.push_back(v);
     520                ICmpRangeManager::ELosVisibility vis = cmpRangeManager->GetLosVisibility(it->first, g_Game->GetPlayerID());
     521                if (vis != ICmpRangeManager::VIS_HIDDEN)
     522                {
     523                    v.a = 255;
     524                    v.x = posX.ToFloat()*sx;
     525                    v.y = -posZ.ToFloat()*sy;
     526
     527                   
     528                    (*attrColor)[0] = v.r;
     529                    (*attrColor)[1] = v.g;
     530                    (*attrColor)[2] = v.b;
     531                    (*attrColor)[3] = v.a;
     532                    ++attrColor;
     533
     534                    (*attrPos)[0] = v.x;
     535                    (*attrPos)[1] = v.y;
     536       
     537                    ++attrPos;
     538
     539                    m_UnitDrawn++;
     540                }
    473541            }
    474542        }
     543        ENSURE(m_UnitDrawn < maxEntitiesDrawn);
     544        m_VertexArray.Upload();
    475545    }
    476546
    477     if (!vertexArray.empty())
    478     {
    479         glEnableClientState(GL_VERTEX_ARRAY);
    480         glEnableClientState(GL_COLOR_ARRAY);
    481        
     547    if (m_UnitDrawn > 0)
     548    {       
     549        // Don't enable GL_POINT_SMOOTH because it's far too slow
     550        // (~70msec/frame on a GF4 rendering a thousand points)
     551        glPointSize(3.f);
     552
     553        u8* indexBase = m_IndexArray.Bind();
     554        u8* base = m_VertexArray.Bind();
     555        const GLsizei stride = (GLsizei)m_VertexArray.GetStride();
     556
    482557        if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
    483558        {
    484             shader->VertexPointer(2, GL_FLOAT, sizeof(MinimapUnitVertex), &vertexArray[0].x);
    485             shader->ColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MinimapUnitVertex), &vertexArray[0].r);
     559            shader->VertexPointer(2, GL_FLOAT, stride, base + m_AttributePos.offset);
     560            shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset);
     561            shader->AssertPointersBound();
    486562        }
    487563        else
     564        {   
     565            glEnableClientState(GL_VERTEX_ARRAY);
     566            glEnableClientState(GL_COLOR_ARRAY);
     567   
     568            glDisable(GL_TEXTURE_2D);
     569            glVertexPointer(2, GL_FLOAT, stride, base + m_AttributePos.offset);
     570            glColorPointer(4, GL_UNSIGNED_BYTE, stride, base + m_AttributeColor.offset);
     571        }
     572       
     573        if (!g_Renderer.m_SkipSubmit)
    488574        {
    489             glVertexPointer(2, GL_FLOAT, sizeof(MinimapUnitVertex), &vertexArray[0].x);
    490             glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(MinimapUnitVertex), &vertexArray[0].r);
     575            glDrawElements(GL_POINTS, (GLsizei)(m_UnitDrawn), GL_UNSIGNED_SHORT, indexBase);
    491576        }
    492577
    493         glDrawArrays(GL_POINTS, 0, (GLsizei)vertexArray.size());
    494 
    495         glDisableClientState(GL_COLOR_ARRAY);
    496         glDisableClientState(GL_VERTEX_ARRAY);
     578       
     579        g_Renderer.GetStats().m_DrawCalls++;
     580        CVertexBuffer::Unbind();
    497581    }
    498582
    499583    PROFILE_END("minimap units");
     
    508592        tech->BeginPass();
    509593        shader = tech->GetShader();
    510594    }
     595    else
     596    {
     597        glEnable(GL_TEXTURE_2D);
     598        glDisableClientState(GL_VERTEX_ARRAY);
     599        glDisableClientState(GL_COLOR_ARRAY);
     600    }
    511601
    512602    DrawViewRect();
    513603