CrystalSpace

Public API Reference

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__

Generated for Crystal Space 2.0 by doxygen 1.7.6.1