in DirectXMesh/DirectXMeshVBReader.cpp [283:644]
HRESULT VBReader::Impl::Read(XMVECTOR* buffer, const char* semanticName, unsigned int semanticIndex, size_t count, bool x2bias) const
{
if (!buffer || !semanticName || !count)
return E_INVALIDARG;
auto range = mSemantics.equal_range(semanticName);
auto it = range.first;
for (; it != range.second; ++it)
{
if (mInputDesc[it->second].SemanticIndex == semanticIndex)
break;
}
if (it == range.second)
return HRESULT_E_INVALID_NAME;
uint32_t inputSlot = mInputDesc[it->second].InputSlot;
auto vb = static_cast<const uint8_t*>(mBuffers[inputSlot]);
if (!vb)
return E_FAIL;
if (count > mVerts[inputSlot])
return E_BOUNDS;
uint32_t stride = mStrides[inputSlot];
if (!stride)
return E_UNEXPECTED;
const uint8_t* eptr = vb + stride * mVerts[inputSlot];
const uint8_t* ptr = vb + mInputDesc[it->second].AlignedByteOffset;
switch (static_cast<int>(mInputDesc[it->second].Format))
{
case DXGI_FORMAT_R32G32B32A32_FLOAT:
LOAD_VERTS(XMFLOAT4, XMLoadFloat4)
case DXGI_FORMAT_R32G32B32A32_UINT:
LOAD_VERTS(XMUINT4, XMLoadUInt4)
case DXGI_FORMAT_R32G32B32A32_SINT:
LOAD_VERTS(XMINT4, XMLoadSInt4)
case DXGI_FORMAT_R32G32B32_FLOAT:
LOAD_VERTS(XMFLOAT3, XMLoadFloat3)
case DXGI_FORMAT_R32G32B32_UINT:
LOAD_VERTS(XMUINT3, XMLoadUInt3)
case DXGI_FORMAT_R32G32B32_SINT:
LOAD_VERTS(XMINT3, XMLoadSInt3)
case DXGI_FORMAT_R16G16B16A16_FLOAT:
LOAD_VERTS(XMHALF4, XMLoadHalf4)
case DXGI_FORMAT_R16G16B16A16_UNORM:
LOAD_VERTS4_X2(XMUSHORTN4, XMLoadUShortN4, x2bias)
case DXGI_FORMAT_R16G16B16A16_UINT:
LOAD_VERTS(XMUSHORT4, XMLoadUShort4)
case DXGI_FORMAT_R16G16B16A16_SNORM:
LOAD_VERTS(XMSHORTN4, XMLoadShortN4)
case DXGI_FORMAT_R16G16B16A16_SINT:
LOAD_VERTS(XMSHORT4, XMLoadShort4)
case DXGI_FORMAT_R32G32_FLOAT:
LOAD_VERTS(XMFLOAT2, XMLoadFloat2)
case DXGI_FORMAT_R32G32_UINT:
LOAD_VERTS(XMUINT2, XMLoadUInt2)
case DXGI_FORMAT_R32G32_SINT:
LOAD_VERTS(XMINT2, XMLoadSInt2)
case DXGI_FORMAT_R10G10B10A2_UNORM:
LOAD_VERTS3_X2(XMUDECN4, XMLoadUDecN4, x2bias)
case DXGI_FORMAT_R10G10B10A2_UINT:
LOAD_VERTS(XMUDEC4, XMLoadUDec4)
case DXGI_FORMAT_R11G11B10_FLOAT:
LOAD_VERTS3_X2(XMFLOAT3PK, XMLoadFloat3PK, x2bias)
case DXGI_FORMAT_R8G8B8A8_UNORM:
LOAD_VERTS4_X2(XMUBYTEN4, XMLoadUByteN4, x2bias)
case DXGI_FORMAT_R8G8B8A8_UINT:
LOAD_VERTS(XMUBYTE4, XMLoadUByte4)
case DXGI_FORMAT_R8G8B8A8_SNORM:
LOAD_VERTS(XMBYTEN4, XMLoadByteN4)
case DXGI_FORMAT_R8G8B8A8_SINT:
LOAD_VERTS(XMBYTE4, XMLoadByte4)
case DXGI_FORMAT_R16G16_FLOAT:
LOAD_VERTS(XMHALF2, XMLoadHalf2)
case DXGI_FORMAT_R16G16_UNORM:
LOAD_VERTS2_X2(XMUSHORTN2, XMLoadUShortN2, x2bias)
case DXGI_FORMAT_R16G16_UINT:
LOAD_VERTS(XMUSHORT2, XMLoadUShort2)
case DXGI_FORMAT_R16G16_SNORM:
LOAD_VERTS(XMSHORTN2, XMLoadShortN2)
case DXGI_FORMAT_R16G16_SINT:
LOAD_VERTS(XMSHORT2, XMLoadShort2)
case DXGI_FORMAT_R32_FLOAT:
LOAD_VERTS(float, XMLoadFloat)
case DXGI_FORMAT_R32_UINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(uint32_t)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadInt(reinterpret_cast<const uint32_t*>(ptr));
*buffer++ = XMConvertVectorUIntToFloat(v, 0);
ptr += stride;
}
break;
case DXGI_FORMAT_R32_SINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(int32_t)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadInt(reinterpret_cast<const uint32_t*>(ptr));
*buffer++ = XMConvertVectorIntToFloat(v, 0);
ptr += stride;
}
break;
case DXGI_FORMAT_R8G8_UNORM:
LOAD_VERTS2_X2(XMUBYTEN2, XMLoadUByteN2, x2bias)
case DXGI_FORMAT_R8G8_UINT:
LOAD_VERTS(XMUBYTE2, XMLoadUByte2)
case DXGI_FORMAT_R8G8_SNORM:
LOAD_VERTS(XMBYTEN2, XMLoadByteN2)
case DXGI_FORMAT_R8G8_SINT:
LOAD_VERTS(XMBYTE2, XMLoadByte2)
case DXGI_FORMAT_R16_FLOAT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(HALF)) > eptr)
return E_UNEXPECTED;
float v = XMConvertHalfToFloat(*reinterpret_cast<const HALF*>(ptr));
*buffer++ = XMVectorSet(v, 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R16_UNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(uint16_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const uint16_t*>(ptr);
float f = static_cast<float>(i) / 65535.f;
if (x2bias)
{
f = f*2.f - 1.f;
}
XMVECTOR v = XMVectorSet(f, 0.f, 0.f, 0.f);
*buffer++ = v;
ptr += stride;
}
break;
case DXGI_FORMAT_R16_UINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(uint16_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const uint16_t*>(ptr);
*buffer++ = XMVectorSet(static_cast<float>(i), 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R16_SNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(int16_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const int16_t*>(ptr);
*buffer++ = XMVectorSet(static_cast<float>(i) / 32767.f, 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R16_SINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(int16_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const int16_t*>(ptr);
*buffer++ = XMVectorSet(static_cast<float>(i), 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R8_UNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(uint8_t)) > eptr)
return E_UNEXPECTED;
const uint8_t i = *ptr;
float f = static_cast<float>(i) / 255.f;
if (x2bias)
{
f = f*2.f - 1.f;
}
XMVECTOR v = XMVectorSet(f, 0.f, 0.f, 0.f);
*buffer++ = v;
ptr += stride;
}
break;
case DXGI_FORMAT_R8_UINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(uint8_t)) > eptr)
return E_UNEXPECTED;
const uint8_t i = *ptr;
*buffer++ = XMVectorSet(static_cast<float>(i), 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R8_SNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(int8_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const int8_t*>(ptr);
*buffer++ = XMVectorSet(static_cast<float>(i) / 127.f, 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_R8_SINT:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(int8_t)) > eptr)
return E_UNEXPECTED;
auto i = *reinterpret_cast<const int8_t*>(ptr);
*buffer++ = XMVectorSet(static_cast<float>(i), 0.f, 0.f, 0.f);
ptr += stride;
}
break;
case DXGI_FORMAT_B5G6R5_UNORM:
{
static const XMVECTORF32 s_Scale = { { { 1.f / 31.f, 1.f / 63.f, 1.f / 31.f, 1.f } } };
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(XMU565)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadU565(reinterpret_cast<const XMU565*>(ptr));
v = XMVectorMultiply(v, s_Scale);
if (x2bias)
{
XMVECTOR v2 = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
v = XMVectorSelect(v, v2, g_XMSelect1110);
}
*buffer++ = XMVectorSwizzle<2, 1, 0, 3>(v);
ptr += stride;
}
}
break;
case DXGI_FORMAT_B5G5R5A1_UNORM:
{
static const XMVECTORF32 s_Scale = { { { 1.f / 31.f, 1.f / 31.f, 1.f / 31.f, 1.f } } };
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(XMU555)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadU555(reinterpret_cast<const XMU555*>(ptr));
v = XMVectorMultiply(v, s_Scale);
if (x2bias)
{
XMVECTOR v2 = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
v = XMVectorSelect(v, v2, g_XMSelect1110);
}
*buffer++ = XMVectorSwizzle<2, 1, 0, 3>(v);
ptr += stride;
}
}
break;
case DXGI_FORMAT_B8G8R8A8_UNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(XMUBYTEN4)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadUByteN4(reinterpret_cast<const XMUBYTEN4*>(ptr));
if (x2bias)
{
v = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
}
*buffer++ = XMVectorSwizzle<2, 1, 0, 3>(v);
ptr += stride;
}
break;
case DXGI_FORMAT_B8G8R8X8_UNORM:
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(XMUBYTEN4)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadUByteN4(reinterpret_cast<const XMUBYTEN4*>(ptr));
if (x2bias)
{
XMVECTOR v2 = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
v = XMVectorSelect(v, v2, g_XMSelect1110);
}
v = XMVectorSwizzle<2, 1, 0, 3>(v);
*buffer++ = XMVectorSelect(g_XMZero, v, g_XMSelect1110);
ptr += stride;
}
break;
case DXGI_FORMAT_B4G4R4A4_UNORM:
{
static const XMVECTORF32 s_Scale = { { { 1.f / 15.f, 1.f / 15.f, 1.f / 15.f, 1.f / 15.f } } };
for (size_t icount = 0; icount < count; ++icount)
{
if ((ptr + sizeof(XMUNIBBLE4)) > eptr)
return E_UNEXPECTED;
XMVECTOR v = XMLoadUNibble4(reinterpret_cast<const XMUNIBBLE4*>(ptr));
v = XMVectorMultiply(v, s_Scale);
if (x2bias)
{
v = XMVectorMultiplyAdd(v, g_XMTwo, g_XMNegativeOne);
}
*buffer++ = XMVectorSwizzle<2, 1, 0, 3>(v);
ptr += stride;
}
}
break;
case XBOX_DXGI_FORMAT_R10G10B10_SNORM_A2_UNORM:
// Xbox One specific format
LOAD_VERTS(XMXDECN4, XMLoadXDecN4)
default:
return E_FAIL;
}
return S_OK;
}