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.6.1