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 mHasNormal( false ), 78 mHasColor( false ), 79 mHasTangent( false ), 80 mHasInstancing( false ), 81 mHasBlendIndices(false), 82 mTexCoordCount( 0 ), 83 mSizeInBytes( 0 ), 84 mDecl( NULL ) 85{ 86 VECTOR_SET_ASSOCIATION( mElements ); 87} 88 89void GFXVertexFormat::copy( const GFXVertexFormat &format ) 90{ 91 mDirty = format.mDirty; 92 mHasNormal = format.mHasNormal; 93 mHasTangent = format.mHasTangent; 94 mHasColor = format.mHasColor; 95 mHasInstancing = format.mHasInstancing; 96 mHasBlendIndices = format.mHasBlendIndices; 97 mTexCoordCount = format.mTexCoordCount; 98 mSizeInBytes = format.mSizeInBytes; 99 mDescription = format.mDescription; 100 mElements = format.mElements; 101 mDecl = format.mDecl; 102} 103 104void GFXVertexFormat::append( const GFXVertexFormat &format, U32 streamIndex ) 105{ 106 for ( U32 i=0; i < format.getElementCount(); i++ ) 107 { 108 mElements.increment(); 109 mElements.last() = format.getElement( i ); 110 if ( streamIndex != -1 ) 111 mElements.last().mStreamIndex = streamIndex; 112 } 113 114 mDirty = true; 115} 116 117void GFXVertexFormat::clear() 118{ 119 mDirty = true; 120 mElements.clear(); 121 mDecl = NULL; 122} 123 124void GFXVertexFormat::addElement( const String& semantic, GFXDeclType type, U32 index, U32 stream ) 125{ 126 mDirty = true; 127 mElements.increment(); 128 GFXVertexElement& lastElement = mElements.last(); 129 lastElement.mStreamIndex = stream; 130 lastElement.mSemantic = semantic.intern(); 131 lastElement.mSemanticIndex = index; 132 lastElement.mType = type; 133} 134 135const String& GFXVertexFormat::getDescription() const 136{ 137 if ( mDirty ) 138 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 139 140 return mDescription; 141} 142 143GFXVertexDecl* GFXVertexFormat::getDecl() const 144{ 145 if ( !mDecl || mDirty ) 146 const_cast<GFXVertexFormat*>(this)->_updateDecl(); 147 148 return mDecl; 149} 150 151bool GFXVertexFormat::hasNormal() const 152{ 153 if ( mDirty ) 154 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 155 156 return mHasNormal; 157} 158 159bool GFXVertexFormat::hasTangent() const 160{ 161 if ( mDirty ) 162 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 163 164 return mHasTangent; 165} 166 167bool GFXVertexFormat::hasColor() const 168{ 169 if ( mDirty ) 170 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 171 172 return mHasColor; 173} 174 175bool GFXVertexFormat::hasInstancing() const 176{ 177 if (mDirty) 178 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 179 180 return mHasInstancing; 181} 182 183bool GFXVertexFormat::hasBlendIndices() const 184{ 185 if ( mDirty ) 186 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 187 188 return mHasBlendIndices; 189} 190 191U32 GFXVertexFormat::getNumBlendIndices() const 192{ 193 if ( mDirty ) 194 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 195 196 if ( !mHasBlendIndices ) 197 return 0; 198 199 U32 numIndices = 0; 200 201 for ( U32 i=0; i < mElements.size(); i++ ) 202 { 203 const GFXVertexElement &element = mElements[i]; 204 205 if ( element.isSemantic( GFXSemantic::BLENDINDICES ) ) 206 numIndices++; 207 } 208 209 return numIndices; 210} 211 212U32 GFXVertexFormat::getTexCoordCount() const 213{ 214 if ( mDirty ) 215 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 216 217 return mTexCoordCount; 218} 219 220U32 GFXVertexFormat::getSizeInBytes() const 221{ 222 if ( mDirty ) 223 const_cast<GFXVertexFormat*>(this)->_updateDirty(); 224 225 return mSizeInBytes; 226} 227 228void GFXVertexFormat::enableInstancing() 229{ 230 mHasInstancing = true; 231} 232 233void GFXVertexFormat::_updateDirty() 234{ 235 PROFILE_SCOPE( GFXVertexFormat_updateDirty ); 236 237 mTexCoordCount = 0; 238 239 mHasColor = false; 240 mHasBlendIndices = false; 241 mHasNormal = false; 242 mHasTangent = false; 243 mSizeInBytes = 0; 244 245 String desc; 246 247 for ( U32 i=0; i < mElements.size(); i++ ) 248 { 249 const GFXVertexElement &element = mElements[i]; 250 251 desc += String::ToString( "%d,%s,%d,%d\n", element.mStreamIndex, 252 element.mSemantic.c_str(), 253 element.mSemanticIndex, 254 element.mType ); 255 256 if ( element.isSemantic( GFXSemantic::NORMAL ) ) 257 mHasNormal = true; 258 else if ( element.isSemantic( GFXSemantic::TANGENT ) ) 259 mHasTangent = true; 260 else if ( element.isSemantic( GFXSemantic::COLOR ) ) 261 mHasColor = true; 262 else if ( element.isSemantic( GFXSemantic::TEXCOORD ) ) 263 ++mTexCoordCount; 264 else if ( element.isSemantic( GFXSemantic::BLENDINDICES ) ) 265 mHasBlendIndices = true; 266 267 mSizeInBytes += element.getSizeInBytes(); 268 } 269 270 // Intern the string for fast compares later. 271 mDescription = desc.intern(); 272 273 mDirty = false; 274} 275 276void GFXVertexFormat::_updateDecl() 277{ 278 PROFILE_SCOPE( GFXVertexFormat_updateDecl ); 279 280 if ( mDirty ) 281 _updateDirty(); 282 283 mDecl = GFX->allocVertexDecl( this ); 284} 285