#include "BsVertexDeclaration.h" #include "BsVertexDeclarationRTTI.h" #include "BsHardwareBufferManager.h" #include "BsRenderAPI.h" namespace BansheeEngine { VertexElement::VertexElement(UINT16 source, UINT32 offset, VertexElementType theType, VertexElementSemantic semantic, UINT16 index) : mSource(source), mOffset(offset), mType(theType), mSemantic(semantic), mIndex(index) { } UINT32 VertexElement::getSize(void) const { return getTypeSize(mType); } UINT32 VertexElement::getTypeSize(VertexElementType etype) { switch(etype) { case VET_COLOR: case VET_COLOR_ABGR: case VET_COLOR_ARGB: return sizeof(RGBA); case VET_FLOAT1: return sizeof(float); case VET_FLOAT2: return sizeof(float)*2; case VET_FLOAT3: return sizeof(float)*3; case VET_FLOAT4: return sizeof(float)*4; case VET_SHORT1: return sizeof(short); case VET_SHORT2: return sizeof(short)*2; case VET_SHORT3: return sizeof(short)*3; case VET_SHORT4: return sizeof(short)*4; case VET_UBYTE4: return sizeof(unsigned char)*4; } return 0; } unsigned short VertexElement::getTypeCount(VertexElementType etype) { switch (etype) { case VET_COLOR: case VET_COLOR_ABGR: case VET_COLOR_ARGB: return 4; case VET_FLOAT1: return 1; case VET_FLOAT2: return 2; case VET_FLOAT3: return 3; case VET_FLOAT4: return 4; case VET_SHORT1: return 1; case VET_SHORT2: return 2; case VET_SHORT3: return 3; case VET_SHORT4: return 4; case VET_UBYTE4: return 4; } BS_EXCEPT(InvalidParametersException, "Invalid type"); } VertexElementType VertexElement::getBestColorVertexElementType() { // Use the current render system to determine if possible if (BansheeEngine::RenderAPICore::instancePtr()) { return BansheeEngine::RenderAPICore::instancePtr()->getColorVertexElementType(); } else { // We can't know the specific type right now, so pick a type // based on platform #if BS_PLATFORM == BS_PLATFORM_WIN32 return VET_COLOR_ARGB; // prefer D3D format on windows #else return VET_COLOR_ABGR; // prefer GL format on everything else #endif } } bool VertexElement::operator== (const VertexElement& rhs) const { if (mType != rhs.mType || mIndex != rhs.mIndex || mOffset != rhs.mOffset || mSemantic != rhs.mSemantic || mSource != rhs.mSource) { return false; } else return true; } bool VertexElement::operator!= (const VertexElement& rhs) const { return !(*this == rhs); } VertexDeclarationProperties::VertexDeclarationProperties(const List& elements) { for (auto& elem : elements) { VertexElementType type = elem.getType(); if (elem.getType() == VET_COLOR) type = VertexElement::getBestColorVertexElementType(); mElementList.push_back(VertexElement(elem.getStreamIdx(), elem.getOffset(), type, elem.getSemantic(), elem.getSemanticIdx())); } } bool VertexDeclarationProperties::operator== (const VertexDeclarationProperties& rhs) const { if (mElementList.size() != rhs.mElementList.size()) return false; auto myIter = mElementList.begin(); auto theirIter = rhs.mElementList.begin(); for (; myIter != mElementList.end() && theirIter != rhs.mElementList.end(); ++myIter, ++theirIter) { if (!(*myIter == *theirIter)) return false; } return true; } bool VertexDeclarationProperties::operator!= (const VertexDeclarationProperties& rhs) const { return !(*this == rhs); } const VertexElement* VertexDeclarationProperties::getElement(UINT16 index) const { assert(index < mElementList.size() && "Index out of bounds"); auto iter = mElementList.begin(); for (UINT16 i = 0; i < index; ++i) ++iter; return &(*iter); } const VertexElement* VertexDeclarationProperties::findElementBySemantic(VertexElementSemantic sem, UINT16 index) const { for (auto& elem : mElementList) { if (elem.getSemantic() == sem && elem.getSemanticIdx() == index) { return &elem; } } return nullptr; } List VertexDeclarationProperties::findElementsBySource(UINT16 source) const { List retList; for (auto& elem : mElementList) { if (elem.getStreamIdx() == source) { retList.push_back(elem); } } return retList; } UINT32 VertexDeclarationProperties::getVertexSize(UINT16 source) const { UINT32 size = 0; for (auto& elem : mElementList) { if (elem.getStreamIdx() == source) { size += elem.getSize(); } } return size; } UINT32 VertexDeclarationCore::NextFreeId = 0; VertexDeclarationCore::VertexDeclarationCore(const List& elements) :mProperties(elements) { } void VertexDeclarationCore::initialize() { mId = NextFreeId++; CoreObjectCore::initialize(); } VertexDeclaration::VertexDeclaration(const List& elements) :mProperties(elements) { } SPtr VertexDeclaration::getCore() const { return std::static_pointer_cast(mCoreSpecific); } SPtr VertexDeclaration::createCore() const { return HardwareBufferCoreManager::instance().createVertexDeclarationInternal(mProperties.mElementList); } VertexDeclarationPtr VertexDeclaration::createVertexDeclaration(const List& elements) { return HardwareBufferManager::instance().createVertexDeclaration(elements); } /************************************************************************/ /* SERIALIZATION */ /************************************************************************/ RTTITypeBase* VertexDeclaration::getRTTIStatic() { return VertexDeclarationRTTI::instance(); } RTTITypeBase* VertexDeclaration::getRTTI() const { return getRTTIStatic(); } }