Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00201
00202
00203
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__