csgfx/vertexlistwalker.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

csgfx/vertexlistwalker.h
Go to the documentation of this file.

    00001 /*
    00002   Copyright (C) 2005 by Marten Svanfeldt
    00003             (C) 2006 by Frank Richter
    00004
    00005   This library is free software; you can redistribute it and/or
    00006   modify it under the terms of the GNU Library General Public
    00007   License as published by the Free Software Foundation; either
    00008   version 2 of the License, or (at your option) any later version.
    00009
    00010   This library is distributed in the hope that it will be useful,
    00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013   Library General Public License for more details.
    00014
    00015   You should have received a copy of the GNU Library General Public
    00016   License along with this library; if not, write to the Free
    00017   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    00018 */
    00019
    00020 #ifndef __CS_CSGFX_VERTEXLISTWALKER_H__
    00021 #define __CS_CSGFX_VERTEXLISTWALKER_H__
    00022
    00023 #include "csutil/csendian.h"
    00024 #include "cstool/rbuflock.h"
    00025
    00042 template<typename Tbase, typename Tcomplex = Tbase[4]>
    00043 class csVertexListWalker
    00044 {
    00045 public:
    00056   csVertexListWalker (iRenderBuffer* buffer, size_t desiredComponents = 0,
    00057     const Tbase* defaultComponents = 0) : currElement (0),
    00058     bufLock (buffer, CS_BUF_LOCK_READ), defaultComponents (defaultComponents)
    00059   {
    00060     bufferComponents = buffer ? buffer->GetComponentCount () : 0;
    00061     components = (desiredComponents != 0) ? desiredComponents :
    00062       bufferComponents;
    00063     if (buffer)
    00064     {
    00065       elements = buffer->GetElementCount();
    00066       compType = buffer->GetComponentType();
    00067       FetchCurrentElement();
    00068     }
    00069     else
    00070     {
    00071       elements = 0;
    00072       compType = (csRenderBufferComponentType)~0;
    00073     }
    00074   }
    00075
    00077
    00078   operator Tcomplex const& () const
    00079   {
    00080     CS_ASSERT(currElement<elements);
    00081     return converted;
    00082   }
    00083   const Tcomplex& operator*() const
    00084   {
    00085     CS_ASSERT(currElement<elements);
    00086     return converted;
    00087   }
    00089
    00091
    00092   csVertexListWalker& operator++ ()
    00093   {
    00094     currElement++;
    00095     FetchCurrentElement();
    00096     return *this;
    00097   }
    00099
    00101   void ResetState ()
    00102   {
    00103     currElement = 0;
    00104     FetchCurrentElement();
    00105   }
    00106
    00108   size_t GetSize() const { return elements; }
    00109
    00111   void SetElement (size_t newElement)
    00112   {
    00113     CS_ASSERT(newElement < elements);
    00114     currElement = newElement;
    00115     FetchCurrentElement();
    00116   }
    00117 private:
    00119   size_t elements;
    00121   size_t currElement;
    00123   csRenderBufferLock<uint8> bufLock;
    00124
    00126   size_t components;
    00128   size_t bufferComponents;
    00130   Tcomplex converted;
    00132   const Tbase* const defaultComponents;
    00134   csRenderBufferComponentType compType;
    00135
    00137   const Tbase GetDefaultComponent (size_t n)
    00138   {
    00139     return (defaultComponents != 0) ? defaultComponents[n] :
    00140       ((n == 3) ? Tbase(1) : Tbase(0));
    00141   }
    00143
    00144   template<typename C>
    00145   void FetchCurrentElementReal()
    00146   {
    00147     uint8* data = bufLock + (currElement * bufferComponents * sizeof (C));
    00148     for (size_t c = 0; c < components; c++)
    00149     {
    00150       converted[c] =
    00151         (c < bufferComponents) ? Tbase(*(C*)data) :
    00152         GetDefaultComponent (c);
    00153       data += sizeof (C);
    00154     }
    00155   }
    00156
    00157   void FetchCurrentElementHalf()
    00158   {
    00159     uint16* data = (uint16*)((uint8*)bufLock) + (currElement * bufferComponents);
    00160     for (size_t c = 0; c < components; c++)
    00161     {
    00162       converted[c] =
    00163         (c < bufferComponents) ? Tbase (csIEEEfloat::ToNative (*data)) :
    00164         GetDefaultComponent (c);
    00165       data++;
    00166     }
    00167   }
    00168
    00169   template<typename C, bool Signed, int range>
    00170   void FetchCurrentElementRealNorm()
    00171   {
    00172     uint8* data = bufLock + (currElement * bufferComponents * sizeof (C));
    00173     for (size_t c = 0; c < components; c++)
    00174     {
    00175       Tbase newComp;
    00176       if (c < bufferComponents)
    00177       {
    00178         double orgVal = double (*(C*)data);
    00179         if (Signed)
    00180         {
    00181           orgVal = (orgVal + (-range - 1)) / double ((int64)range*2+1);
    00182           newComp = Tbase (-1.0 + orgVal * 2.0);
    00183         }
    00184         else
    00185         {
    00186           orgVal = orgVal / double (range);
    00187           newComp = Tbase (orgVal);
    00188         }
    00189       }
    00190       else
    00191         newComp = GetDefaultComponent (c);
    00192       converted[c] = newComp;
    00193       data += sizeof (C);
    00194     }
    00195   }
    00197
    00198   void FetchCurrentElement()
    00199   {
    00200     /* Avoid reading beyond buffer end
    00201      * Don't assert here since FetchCurrentElement() is also called in
    00202      * legitimate cases (i.e. operator++ while on the last valid element.
    00203      * Assert in retrieval operators, though.
    00204      */
    00205     if (currElement >= elements) return;
    00206     switch (compType)
    00207     {
    00208       default:
    00209         CS_ASSERT(false);
    00210       case CS_BUFCOMP_BYTE:
    00211         FetchCurrentElementReal<char>();
    00212         break;
    00213       case CS_BUFCOMP_BYTE_NORM:
    00214         FetchCurrentElementRealNorm<char, true, 127>();
    00215         break;
    00216       case CS_BUFCOMP_UNSIGNED_BYTE:
    00217         FetchCurrentElementReal<unsigned char>();
    00218         break;
    00219       case CS_BUFCOMP_UNSIGNED_BYTE_NORM:
    00220         FetchCurrentElementRealNorm<unsigned char, false, 255>();
    00221         break;
    00222       case CS_BUFCOMP_SHORT:
    00223         FetchCurrentElementReal<short>();
    00224         break;
    00225       case CS_BUFCOMP_SHORT_NORM:
    00226         FetchCurrentElementRealNorm<short, true, 32767>();
    00227         break;
    00228       case CS_BUFCOMP_UNSIGNED_SHORT:
    00229         FetchCurrentElementReal<unsigned short>();
    00230         break;
    00231       case CS_BUFCOMP_UNSIGNED_SHORT_NORM:
    00232         FetchCurrentElementRealNorm<unsigned short, false, 65535>();
    00233         break;
    00234       case CS_BUFCOMP_INT:
    00235         FetchCurrentElementReal<int>();
    00236         break;
    00237       case CS_BUFCOMP_INT_NORM:
    00238         FetchCurrentElementRealNorm<int, true, 2147483647>();
    00239         break;
    00240       case CS_BUFCOMP_UNSIGNED_INT:
    00241         FetchCurrentElementReal<unsigned int>();
    00242         break;
    00243       case CS_BUFCOMP_UNSIGNED_INT_NORM:
    00244         FetchCurrentElementRealNorm<unsigned int, false, 4294967295u>();
    00245         break;
    00246       case CS_BUFCOMP_FLOAT:
    00247         FetchCurrentElementReal<float>();
    00248         break;
    00249       case CS_BUFCOMP_DOUBLE:
    00250         FetchCurrentElementReal<double>();
    00251         break;
    00252       case CS_BUFCOMP_HALF:
    00253         FetchCurrentElementHalf ();
    00254         break;
    00255     }
    00256   }
    00257 };
    00258
    00259 #endif // __CS_CSGFX_VERTEXLISTWALKER_H__