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 "cstool/rbuflock.h" 00024 00041 template<typename Tbase, typename Tcomplex = Tbase> 00042 class csVertexListWalker 00043 { 00044 public: 00055 csVertexListWalker (iRenderBuffer* buffer, size_t desiredComponents = 0, 00056 const Tbase* defaultComponents = 0) : currElement (0), 00057 bufLock (buffer, CS_BUF_LOCK_READ), defaultComponents (defaultComponents) 00058 { 00059 bufferComponents = buffer ? buffer->GetComponentCount () : 0; 00060 components = (desiredComponents != 0) ? desiredComponents : 00061 bufferComponents; 00062 CS_ASSERT (components <= maxComponents); 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 Tbase const*() const 00079 { 00080 CS_ASSERT(currElement<elements); 00081 return convertedComps; 00082 } 00083 const Tcomplex& operator*() const 00084 { 00085 CS_ASSERT(currElement<elements); 00086 const Tbase* x = convertedComps; 00087 const Tcomplex* y = (Tcomplex*)x; 00088 return *y; 00089 } 00091 00093 00094 csVertexListWalker& operator++ () 00095 { 00096 currElement++; 00097 FetchCurrentElement(); 00098 return *this; 00099 } 00101 00103 void ResetState () 00104 { 00105 currElement = 0; 00106 FetchCurrentElement(); 00107 } 00108 00110 size_t GetSize() const { return elements; } 00111 private: 00113 size_t elements; 00115 size_t currElement; 00117 csRenderBufferLock<uint8> bufLock; 00118 00120 size_t components; 00122 size_t bufferComponents; 00124 enum { maxComponents = 4 }; 00126 Tbase convertedComps[maxComponents]; 00128 const Tbase* const defaultComponents; 00130 csRenderBufferComponentType compType; 00131 00133 const Tbase GetDefaultComponent (size_t n) 00134 { 00135 return (defaultComponents != 0) ? defaultComponents[n] : 00136 ((n == 3) ? Tbase(1) : Tbase(0)); 00137 } 00139 00140 template<typename C> 00141 void FetchCurrentElementReal() 00142 { 00143 uint8* data = bufLock + (currElement * bufferComponents * sizeof (C)); 00144 for (size_t c = 0; c < components; c++) 00145 { 00146 convertedComps[c] = 00147 (c < bufferComponents) ? Tbase(*(C*)data) : 00148 GetDefaultComponent (c); 00149 data += sizeof (C); 00150 } 00151 } 00152 template<typename C, bool Signed, int range> 00153 void FetchCurrentElementRealNorm() 00154 { 00155 uint8* data = bufLock + (currElement * bufferComponents * sizeof (C)); 00156 for (size_t c = 0; c < components; c++) 00157 { 00158 Tbase newComp; 00159 if (c < bufferComponents) 00160 { 00161 double orgVal = double (*(C*)data); 00162 if (Signed) 00163 { 00164 orgVal = (orgVal + (-range - 1)) / double ((int64)range*2+1); 00165 newComp = Tbase (-1.0 + orgVal * 2.0); 00166 } 00167 else 00168 { 00169 orgVal = orgVal / double (range); 00170 newComp = Tbase (orgVal); 00171 } 00172 } 00173 else 00174 newComp = GetDefaultComponent (c); 00175 convertedComps[c] = newComp; 00176 data += sizeof (C); 00177 } 00178 } 00180 00181 void FetchCurrentElement() 00182 { 00183 /* Avoid reading beyond buffer end 00184 * Don't assert here since FetchCurrentElement() is also called in 00185 * legitimate cases (i.e. operator++ while on the last valid element. 00186 * Assert in retrieval operators, though. 00187 */ 00188 if (currElement >= elements) return; 00189 switch (compType) 00190 { 00191 default: 00192 CS_ASSERT(false); 00193 case CS_BUFCOMP_BYTE: 00194 FetchCurrentElementReal<char>(); 00195 break; 00196 case CS_BUFCOMP_BYTE_NORM: 00197 FetchCurrentElementRealNorm<char, true, 127>(); 00198 break; 00199 case CS_BUFCOMP_UNSIGNED_BYTE: 00200 FetchCurrentElementReal<unsigned char>(); 00201 break; 00202 case CS_BUFCOMP_UNSIGNED_BYTE_NORM: 00203 FetchCurrentElementRealNorm<unsigned char, false, 255>(); 00204 break; 00205 case CS_BUFCOMP_SHORT: 00206 FetchCurrentElementReal<short>(); 00207 break; 00208 case CS_BUFCOMP_SHORT_NORM: 00209 FetchCurrentElementRealNorm<short, true, 32767>(); 00210 break; 00211 case CS_BUFCOMP_UNSIGNED_SHORT: 00212 FetchCurrentElementReal<unsigned short>(); 00213 break; 00214 case CS_BUFCOMP_UNSIGNED_SHORT_NORM: 00215 FetchCurrentElementRealNorm<unsigned short, false, 65535>(); 00216 break; 00217 case CS_BUFCOMP_INT: 00218 FetchCurrentElementReal<int>(); 00219 break; 00220 case CS_BUFCOMP_INT_NORM: 00221 FetchCurrentElementRealNorm<int, true, 2147483647>(); 00222 break; 00223 case CS_BUFCOMP_UNSIGNED_INT: 00224 FetchCurrentElementReal<unsigned int>(); 00225 break; 00226 case CS_BUFCOMP_UNSIGNED_INT_NORM: 00227 FetchCurrentElementRealNorm<unsigned int, false, 4294967295u>(); 00228 break; 00229 case CS_BUFCOMP_FLOAT: 00230 FetchCurrentElementReal<float>(); 00231 break; 00232 case CS_BUFCOMP_DOUBLE: 00233 FetchCurrentElementReal<double>(); 00234 break; 00235 } 00236 } 00237 }; 00238 00239 #endif // __CS_CSGFX_VERTEXLISTWALKER_H__
Generated for Crystal Space 1.4.0 by doxygen 1.5.8