gfxVertexFormat.cpp
Engine/source/gfx/gfxVertexFormat.cpp
Namespaces:
namespace
The known Torque vertex element semantics.
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "gfx/gfxVertexFormat.h" 26 27#include "platform/profiler.h" 28#include "core/util/hashFunction.h" 29#include "gfx/gfxDevice.h" 30 31 32namespace GFXSemantic 33{ 34 const String POSITION = String( "POSITION" ).intern(); 35 const String NORMAL = String( "NORMAL" ).intern(); 36 const String BINORMAL = String( "BINORMAL" ).intern(); 37 const String TANGENT = String( "TANGENT" ).intern(); 38 const String TANGENTW = String( "TANGENTW" ).intern(); 39 const String COLOR = String( "COLOR" ).intern(); 40 const String TEXCOORD = String( "TEXCOORD" ).intern(); 41 const String BLENDINDICES = String( "BLENDINDICES" ).intern(); 42 const String BLENDWEIGHT = String( "BLENDWEIGHT" ).intern(); 43 const String PADDING = String( "PADDING" ).intern(); 44} 45 46 47U32 GFXVertexElement::getSizeInBytes() const 48{ 49 switch ( mType ) 50 { 51 case GFXDeclType_Float: 52 return 4; 53 54 case GFXDeclType_Float2: 55 return 8; 56 57 case GFXDeclType_Float3: 58 return 12; 59 60 case GFXDeclType_Float4: 61 return 16; 62 63 case GFXDeclType_Color: 64 return 4; 65 66 case GFXDeclType_UByte4: 67 return 4; 68 69 default: 70 return 0; 71 }; 72} 73 74 75GFXVertexFormat::GFXVertexFormat() 76 : mDirty( true ), 77 mHasColor( false ), 78 mHasNormal( false ), 79 mHasTangent( false ), 80 mHasInstancing( false ), 81 mTexCoordCount( 0 ), 82 mSizeInBytes( 0 ), 83 mDecl( NULL ) 84{ 85 VECTOR_SET_ASSOCIATION( mElements ); 86} 87 88void GFXVertexFormat::copy( const GFXVertexFormat &format ) 89{ 90 mDirty = format.mDirty; 91 mHasNormal = format.mHasNormal; 92 mHasTangent = format.mHasTangent; 93 mHasColor = format.mHasColor; 94 mHasInstancing = format.mHasInstancing; 95 mHasBlendIndices = format.mHasBlendIndices; 96 mTexCoordCount = format.mTexCoordCount; 97 mSizeInBytes = format.mSizeInBytes; 98 mDescription = format.mDescription; 99 mElements = format.mElements; 100 mDecl = format.mDecl; 101} 102 103void GFXVertexFormat::append( const GFXVertexFormat &format, U32 streamIndex ) 104{ 105 for ( U32 i=0; i < format.getElementCount(); i++ ) 106 { 107 mElements.increment(); 108 mElements.last() = format.getElement( i ); 109 if ( streamIndex != -1 ) 110 mElements.last().mStreamIndex = streamIndex; 111 } 112 113 mDirty = true; 114} 115 116void GFXVertexFormat::clear() 117{ 118 mDirty = true; 119 mElements.clear(); 120 mDecl = NULL; 121} 122 123void GFXVertexFormat::addElement( const String& semantic, GFXDeclType type, U32 index, U32 stream ) 124{ 125 mDirty = true; 126 mElements.increment(); 127 GFXVertexElement& lastElement = mElements.last(); 128 lastElement.mStreamIndex = stream; 129 lastElement.mSemantic = semantic.intern(); 130 lastElement.mSemanticIndex = index; 131 lastElement.mType = type; 132} 133 134const String& GFXVertexFormat::getDescription() const 135{ 136 if ( mDirty ) 137 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 138 139 return mDescription; 140} 141 142GFXVertexDecl* GFXVertexFormat::getDecl() const 143{ 144 if ( !mDecl || mDirty ) 145 const_cast<GFXVertexFormat*>(this)->_updateDecl(); 146 147 return mDecl; 148} 149 150bool GFXVertexFormat::hasNormal() const 151{ 152 if ( mDirty ) 153 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 154 155 return mHasNormal; 156} 157 158bool GFXVertexFormat::hasTangent() const 159{ 160 if ( mDirty ) 161 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 162 163 return mHasTangent; 164} 165 166bool GFXVertexFormat::hasColor() const 167{ 168 if ( mDirty ) 169 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 170 171 return mHasColor; 172} 173 174bool GFXVertexFormat::hasInstancing() const 175{ 176 if (mDirty) 177 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 178 179 return mHasInstancing; 180} 181 182bool GFXVertexFormat::hasBlendIndices() const 183{ 184 if ( mDirty ) 185 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 186 187 return mHasBlendIndices; 188} 189 190U32 GFXVertexFormat::getNumBlendIndices() const 191{ 192 if ( mDirty ) 193 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 194 195 if ( !mHasBlendIndices ) 196 return 0; 197 198 U32 numIndices = 0; 199 200 for ( U32 i=0; i < mElements.size(); i++ ) 201 { 202 const GFXVertexElement &element = mElements[i]; 203 204 if ( element.isSemantic( GFXSemantic::BLENDINDICES ) ) 205 numIndices++; 206 } 207 208 return numIndices; 209} 210 211U32 GFXVertexFormat::getTexCoordCount() const 212{ 213 if ( mDirty ) 214 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 215 216 return mTexCoordCount; 217} 218 219U32 GFXVertexFormat::getSizeInBytes() const 220{ 221 if ( mDirty ) 222 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 223 224 return mSizeInBytes; 225} 226 227void GFXVertexFormat::enableInstancing() 228{ 229 mHasInstancing = true; 230} 231 232void GFXVertexFormat::_updateDirty() 233{ 234 PROFILE_SCOPE( GFXVertexFormat_updateDirty ); 235 236 mTexCoordCount = 0; 237 238 mHasColor = false; 239 mHasBlendIndices = false; 240 mHasNormal = false; 241 mHasTangent = false; 242 mSizeInBytes = 0; 243 244 String desc; 245 246 for ( U32 i=0; i < mElements.size(); i++ ) 247 { 248 const GFXVertexElement &element = mElements[i]; 249 250 desc += String::ToString( "%d,%s,%d,%d\n", element.mStreamIndex, 251 element.mSemantic.c_str(), 252 element.mSemanticIndex, 253 element.mType ); 254 255 if ( element.isSemantic( GFXSemantic::NORMAL ) ) 256 mHasNormal = true; 257 else if ( element.isSemantic( GFXSemantic::TANGENT ) ) 258 mHasTangent = true; 259 else if ( element.isSemantic( GFXSemantic::COLOR ) ) 260 mHasColor = true; 261 else if ( element.isSemantic( GFXSemantic::TEXCOORD ) ) 262 ++mTexCoordCount; 263 else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) ) 264 mHasBlendIndices = true; 265 266 mSizeInBytes += element.getSizeInBytes(); 267 } 268 269 // Intern the string for fast compares later. 270 mDescription = desc.intern(); 271 272 mDirty = false; 273} 274 275void GFXVertexFormat::_updateDecl() 276{ 277 PROFILE_SCOPE( GFXVertexFormat_updateDecl ); 278 279 if ( mDirty ) 280 _updateDirty(); 281 282 mDecl = GFX->allocVertexDecl( this ); 283} 284
