Show
Ignore:
Timestamp:
01/07/10 17:49:12 (5 years ago)
Author:
robert
Message:

From Lilith Bryant, "As discussed previously on the users list. Fixes the redundant calls to
glActiveTexture on every State::apply after more than one texunits have been
used.

This is against 2.9.6 (I think SVN head is the same)

Quick Synopsis:

New functions:

State::applyModeOnTexUnit
State::applyAttributeOnTexUnit
State::applyModeMapOnTexUnit
State::applyAttributeMapOnTexUnit
State::applyModeListOnTexUnit
State::applyAttributeListOnTexUnit

All copies of the normal versions, but they also set the active tex unit if
absolutely necessary (i.e. only if they call something OpenGL).

State::apply (*2)
State::applyTextureAttribute

Changed to call the above functions and no longer call setActiveTextureUnit
themselves.

State::setActiveTextureUnit

Made inline, so the benefit of having applyModeOnTexUnit (etc) inline
is retained.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/State

    r10769 r10926  
    299299        inline bool applyTextureMode(unsigned int unit, StateAttribute::GLMode mode,bool enabled) 
    300300        { 
    301             if (setActiveTextureUnit(unit)) 
    302             { 
    303                 ModeMap& modeMap = getOrCreateTextureModeMap(unit); 
    304                 ModeStack& ms = modeMap[mode]; 
    305                 ms.changed = true; 
    306                 return applyMode(mode,enabled,ms); 
    307             } 
    308             else 
    309                 return false; 
     301            ModeMap& modeMap = getOrCreateTextureModeMap(unit); 
     302            ModeStack& ms = modeMap[mode]; 
     303            ms.changed = true; 
     304            return applyModeOnTexUnit(unit,mode,enabled,ms); 
    310305        } 
    311306 
     
    347342        inline bool applyTextureAttribute(unsigned int unit, const StateAttribute* attribute) 
    348343        { 
    349             if (setActiveTextureUnit(unit)) 
    350             { 
    351                 AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit); 
    352                 AttributeStack& as = attributeMap[attribute->getTypeMemberPair()]; 
    353                 as.changed = true; 
    354                 return applyAttribute(attribute,as); 
    355             } 
    356             else 
    357                 return false; 
     344            AttributeMap& attributeMap = getOrCreateTextureAttributeMap(unit); 
     345            AttributeStack& as = attributeMap[attribute->getTypeMemberPair()]; 
     346            as.changed = true; 
     347            return applyAttributeOnTexUnit(unit,attribute,as); 
    358348        } 
    359349 
     
    11391129        * false if selection failed such as when multi texturing is not supported. 
    11401130        * note, only updates values that change.*/ 
    1141         bool setActiveTextureUnit( unsigned int unit ); 
     1131        inline bool setActiveTextureUnit( unsigned int unit ); 
    11421132 
    11431133        /** Get the current texture unit.*/ 
     
    14561446        } 
    14571447 
     1448        inline bool applyModeOnTexUnit(unsigned int unit,StateAttribute::GLMode mode,bool enabled,ModeStack& ms) 
     1449        { 
     1450            if (ms.valid && ms.last_applied_value != enabled) 
     1451            { 
     1452                if (setActiveTextureUnit(unit)) 
     1453                { 
     1454                    ms.last_applied_value = enabled; 
     1455 
     1456                    if (enabled) glEnable(mode); 
     1457                    else glDisable(mode); 
     1458 
     1459                    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(mode); 
     1460 
     1461                    return true; 
     1462                } 
     1463                else 
     1464                    return false; 
     1465            } 
     1466            else 
     1467                return false; 
     1468        } 
    14581469 
    14591470        /** apply an attribute if required, passing in attribute and appropriate attribute stack */ 
     
    14751486        } 
    14761487 
     1488        inline bool applyAttributeOnTexUnit(unsigned int unit,const StateAttribute* attribute,AttributeStack& as) 
     1489        { 
     1490            if (as.last_applied_attribute != attribute) 
     1491            { 
     1492                if (setActiveTextureUnit(unit)) 
     1493                { 
     1494                    if (!as.global_default_attribute.valid()) as.global_default_attribute = dynamic_cast<StateAttribute*>(attribute->cloneType()); 
     1495 
     1496                    as.last_applied_attribute = attribute; 
     1497                    attribute->apply(*this); 
     1498 
     1499                    if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(attribute); 
     1500 
     1501                    return true; 
     1502                } 
     1503                else 
     1504                    return false; 
     1505            } 
     1506            else 
     1507                return false; 
     1508        } 
     1509 
     1510 
    14771511        inline bool applyGlobalDefaultAttribute(AttributeStack& as) 
    14781512        { 
     
    14861520                } 
    14871521                return true; 
     1522            } 
     1523            else 
     1524                return false; 
     1525        } 
     1526 
     1527        inline bool applyGlobalDefaultAttributeOnTexUnit(unsigned int unit,AttributeStack& as) 
     1528        { 
     1529            if (as.last_applied_attribute != as.global_default_attribute.get()) 
     1530            { 
     1531                if (setActiveTextureUnit(unit)) 
     1532                { 
     1533                    as.last_applied_attribute = as.global_default_attribute.get(); 
     1534                    if (as.global_default_attribute.valid()) 
     1535                    { 
     1536                        as.global_default_attribute->apply(*this); 
     1537                        if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.global_default_attribute.get()); 
     1538                    } 
     1539                    return true; 
     1540                } 
     1541                else 
     1542                    return false; 
    14881543            } 
    14891544            else 
     
    15791634        inline void applyAttributeMap(AttributeMap& attributeMap); 
    15801635        inline void applyUniformMap(UniformMap& uniformMap); 
     1636 
     1637        inline void applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList); 
     1638        inline void applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList); 
     1639 
     1640        inline void applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap); 
     1641        inline void applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap); 
    15811642 
    15821643        void haveAppliedMode(ModeMap& modeMap,StateAttribute::GLMode mode,StateAttribute::GLModeValue value); 
     
    18931954} 
    18941955 
     1956inline void State::applyModeListOnTexUnit(unsigned int unit,ModeMap& modeMap,const StateSet::ModeList& modeList) 
     1957{ 
     1958    StateSet::ModeList::const_iterator ds_mitr = modeList.begin(); 
     1959    ModeMap::iterator this_mitr=modeMap.begin(); 
     1960 
     1961    while (this_mitr!=modeMap.end() && ds_mitr!=modeList.end()) 
     1962    { 
     1963        if (this_mitr->first<ds_mitr->first) 
     1964        { 
     1965 
     1966            // note GLMode = this_mitr->first 
     1967            ModeStack& ms = this_mitr->second; 
     1968            if (ms.changed) 
     1969            { 
     1970                ms.changed = false; 
     1971                if (!ms.valueVec.empty()) 
     1972                { 
     1973                    bool new_value = ms.valueVec.back() & StateAttribute::ON; 
     1974                    applyModeOnTexUnit(unit,this_mitr->first,new_value,ms); 
     1975                } 
     1976                else 
     1977                { 
     1978                    // assume default of disabled. 
     1979                    applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms); 
     1980 
     1981                } 
     1982 
     1983            } 
     1984 
     1985            ++this_mitr; 
     1986 
     1987        } 
     1988        else if (ds_mitr->first<this_mitr->first) 
     1989        { 
     1990 
     1991            // ds_mitr->first is a new mode, therefore 
     1992            // need to insert a new mode entry for ds_mistr->first. 
     1993            ModeStack& ms = modeMap[ds_mitr->first]; 
     1994 
     1995            bool new_value = ds_mitr->second & StateAttribute::ON; 
     1996            applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms); 
     1997 
     1998            // will need to disable this mode on next apply so set it to changed. 
     1999            ms.changed = true; 
     2000 
     2001            ++ds_mitr; 
     2002 
     2003        } 
     2004        else 
     2005        { 
     2006            // this_mitr & ds_mitr refer to the same mode, check the override 
     2007            // if any otherwise just apply the incoming mode. 
     2008 
     2009            ModeStack& ms = this_mitr->second; 
     2010 
     2011            if (!ms.valueVec.empty() && (ms.valueVec.back() & StateAttribute::OVERRIDE) && !(ds_mitr->second & StateAttribute::PROTECTED)) 
     2012            { 
     2013                // override is on, just treat as a normal apply on modes. 
     2014 
     2015                if (ms.changed) 
     2016                { 
     2017                    ms.changed = false; 
     2018                    bool new_value = ms.valueVec.back() & StateAttribute::ON; 
     2019                    applyModeOnTexUnit(unit,this_mitr->first,new_value,ms); 
     2020 
     2021                } 
     2022            } 
     2023            else 
     2024            { 
     2025                // no override on or no previous entry, therefore consider incoming mode. 
     2026                bool new_value = ds_mitr->second & StateAttribute::ON; 
     2027                if (applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms)) 
     2028                { 
     2029                    ms.changed = true; 
     2030                } 
     2031            } 
     2032 
     2033            ++this_mitr; 
     2034            ++ds_mitr; 
     2035        } 
     2036    } 
     2037 
     2038    // iterator over the remaining state modes to apply any previous changes. 
     2039    for(; 
     2040        this_mitr!=modeMap.end(); 
     2041        ++this_mitr) 
     2042    { 
     2043        // note GLMode = this_mitr->first 
     2044        ModeStack& ms = this_mitr->second; 
     2045        if (ms.changed) 
     2046        { 
     2047            ms.changed = false; 
     2048            if (!ms.valueVec.empty()) 
     2049            { 
     2050                bool new_value = ms.valueVec.back() & StateAttribute::ON; 
     2051                applyModeOnTexUnit(unit,this_mitr->first,new_value,ms); 
     2052            } 
     2053            else 
     2054            { 
     2055                // assume default of disabled. 
     2056                applyModeOnTexUnit(unit,this_mitr->first,ms.global_default_value,ms); 
     2057 
     2058            } 
     2059 
     2060        } 
     2061    } 
     2062 
     2063    // iterator over the remaining incoming modes to apply any new mode. 
     2064    for(; 
     2065        ds_mitr!=modeList.end(); 
     2066        ++ds_mitr) 
     2067    { 
     2068        ModeStack& ms = modeMap[ds_mitr->first]; 
     2069 
     2070        bool new_value = ds_mitr->second & StateAttribute::ON; 
     2071        applyModeOnTexUnit(unit,ds_mitr->first,new_value,ms); 
     2072 
     2073        // will need to disable this mode on next apply so set it to changed. 
     2074        ms.changed = true; 
     2075    } 
     2076} 
     2077 
    18952078inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet::AttributeList& attributeList) 
    18962079{ 
     
    20042187        const StateAttribute* new_attr = ds_aitr->second.first.get(); 
    20052188        applyAttribute(new_attr,as); 
     2189 
     2190        // will need to update this attribute on next apply so set it to changed. 
     2191        as.changed = true; 
     2192    } 
     2193 
     2194} 
     2195 
     2196inline void State::applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& attributeMap,const StateSet::AttributeList& attributeList) 
     2197{ 
     2198    StateSet::AttributeList::const_iterator ds_aitr=attributeList.begin(); 
     2199 
     2200    AttributeMap::iterator this_aitr=attributeMap.begin(); 
     2201 
     2202    while (this_aitr!=attributeMap.end() && ds_aitr!=attributeList.end()) 
     2203    { 
     2204        if (this_aitr->first<ds_aitr->first) 
     2205        { 
     2206 
     2207            // note attribute type = this_aitr->first 
     2208            AttributeStack& as = this_aitr->second; 
     2209            if (as.changed) 
     2210            { 
     2211                as.changed = false; 
     2212                if (!as.attributeVec.empty()) 
     2213                { 
     2214                    const StateAttribute* new_attr = as.attributeVec.back().first; 
     2215                    applyAttributeOnTexUnit(unit,new_attr,as); 
     2216                } 
     2217                else 
     2218                { 
     2219                    applyGlobalDefaultAttributeOnTexUnit(unit,as); 
     2220                } 
     2221            } 
     2222 
     2223            ++this_aitr; 
     2224 
     2225        } 
     2226        else if (ds_aitr->first<this_aitr->first) 
     2227        { 
     2228 
     2229            // ds_aitr->first is a new attribute, therefore 
     2230            // need to insert a new attribute entry for ds_aitr->first. 
     2231            AttributeStack& as = attributeMap[ds_aitr->first]; 
     2232 
     2233            const StateAttribute* new_attr = ds_aitr->second.first.get(); 
     2234            applyAttributeOnTexUnit(unit,new_attr,as); 
     2235 
     2236            as.changed = true; 
     2237 
     2238            ++ds_aitr; 
     2239 
     2240        } 
     2241        else 
     2242        { 
     2243            // this_mitr & ds_mitr refer to the same attribute, check the override 
     2244            // if any otherwise just apply the incoming attribute 
     2245 
     2246            AttributeStack& as = this_aitr->second; 
     2247 
     2248            if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED)) 
     2249            { 
     2250                // override is on, just treat as a normal apply on attribute. 
     2251 
     2252                if (as.changed) 
     2253                { 
     2254                    as.changed = false; 
     2255                    const StateAttribute* new_attr = as.attributeVec.back().first; 
     2256                    applyAttributeOnTexUnit(unit,new_attr,as); 
     2257                } 
     2258            } 
     2259            else 
     2260            { 
     2261                // no override on or no previous entry, therefore consider incoming attribute. 
     2262                const StateAttribute* new_attr = ds_aitr->second.first.get(); 
     2263                if (applyAttributeOnTexUnit(unit,new_attr,as)) 
     2264                { 
     2265                    as.changed = true; 
     2266                } 
     2267            } 
     2268 
     2269            ++this_aitr; 
     2270            ++ds_aitr; 
     2271        } 
     2272    } 
     2273 
     2274    // iterator over the remaining state attributes to apply any previous changes. 
     2275    for(; 
     2276        this_aitr!=attributeMap.end(); 
     2277        ++this_aitr) 
     2278    { 
     2279        // note attribute type = this_aitr->first 
     2280        AttributeStack& as = this_aitr->second; 
     2281        if (as.changed) 
     2282        { 
     2283            as.changed = false; 
     2284            if (!as.attributeVec.empty()) 
     2285            { 
     2286                const StateAttribute* new_attr = as.attributeVec.back().first; 
     2287                applyAttributeOnTexUnit(unit,new_attr,as); 
     2288            } 
     2289            else 
     2290            { 
     2291                applyGlobalDefaultAttributeOnTexUnit(unit,as); 
     2292            } 
     2293        } 
     2294    } 
     2295 
     2296    // iterator over the remaining incoming attribute to apply any new attribute. 
     2297    for(; 
     2298        ds_aitr!=attributeList.end(); 
     2299        ++ds_aitr) 
     2300    { 
     2301        // ds_aitr->first is a new attribute, therefore 
     2302        // need to insert a new attribute entry for ds_aitr->first. 
     2303        AttributeStack& as = attributeMap[ds_aitr->first]; 
     2304 
     2305        const StateAttribute* new_attr = ds_aitr->second.first.get(); 
     2306        applyAttributeOnTexUnit(unit,new_attr,as); 
    20062307 
    20072308        // will need to update this attribute on next apply so set it to changed. 
     
    21112412} 
    21122413 
     2414inline void State::applyModeMapOnTexUnit(unsigned int unit,ModeMap& modeMap) 
     2415{ 
     2416    for(ModeMap::iterator mitr=modeMap.begin(); 
     2417        mitr!=modeMap.end(); 
     2418        ++mitr) 
     2419    { 
     2420        // note GLMode = mitr->first 
     2421        ModeStack& ms = mitr->second; 
     2422        if (ms.changed) 
     2423        { 
     2424            ms.changed = false; 
     2425            if (!ms.valueVec.empty()) 
     2426            { 
     2427                bool new_value = ms.valueVec.back() & StateAttribute::ON; 
     2428                applyModeOnTexUnit(unit,mitr->first,new_value,ms); 
     2429            } 
     2430            else 
     2431            { 
     2432                // assume default of disabled. 
     2433                applyModeOnTexUnit(unit,mitr->first,ms.global_default_value,ms); 
     2434            } 
     2435 
     2436        } 
     2437    } 
     2438} 
     2439 
    21132440inline void State::applyAttributeMap(AttributeMap& attributeMap) 
    21142441{ 
     
    21352462} 
    21362463 
     2464inline void State::applyAttributeMapOnTexUnit(unsigned int unit,AttributeMap& attributeMap) 
     2465{ 
     2466    for(AttributeMap::iterator aitr=attributeMap.begin(); 
     2467        aitr!=attributeMap.end(); 
     2468        ++aitr) 
     2469    { 
     2470        AttributeStack& as = aitr->second; 
     2471        if (as.changed) 
     2472        { 
     2473            as.changed = false; 
     2474            if (!as.attributeVec.empty()) 
     2475            { 
     2476                const StateAttribute* new_attr = as.attributeVec.back().first; 
     2477                applyAttributeOnTexUnit(unit,new_attr,as); 
     2478            } 
     2479            else 
     2480            { 
     2481                applyGlobalDefaultAttributeOnTexUnit(unit,as); 
     2482            } 
     2483 
     2484        } 
     2485    } 
     2486} 
     2487 
    21372488inline void State::applyUniformMap(UniformMap& uniformMap) 
    21382489{ 
     
    21512502} 
    21522503 
    2153  
     2504inline bool State::setActiveTextureUnit( unsigned int unit ) 
     2505{ 
     2506    if (unit!=_currentActiveTextureUnit) 
     2507    { 
     2508        if (_glActiveTexture && unit < (unsigned int)(maximum(_glMaxTextureCoords,_glMaxTextureUnits)) ) 
     2509        { 
     2510            _glActiveTexture(GL_TEXTURE0+unit); 
     2511            _currentActiveTextureUnit = unit; 
     2512        } 
     2513        else 
     2514        { 
     2515            return unit==0; 
     2516        } 
     2517    } 
     2518    return true; 
    21542519} 
    21552520 
     2521} 
     2522 
    21562523#endif