diff --git a/source/anim/AnimatedModelProvider.cpp b/source/anim/AnimatedModelProvider.cpp index 014167dcdd63cd14dd83bda185fd2b3759738dc9..a3728936d89b2e0ea6d272394b213f019316cada 100644 --- a/source/anim/AnimatedModelProvider.cpp +++ b/source/anim/AnimatedModelProvider.cpp @@ -30,6 +30,8 @@ void CAnimatedModelProvider::setDevice(IGXDevice *pDevice) { m_pRenderContext = pDevice; +#if 0 + // 72 bytes GXVertexElement layoutDynamicEx[] = { {0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION}, @@ -41,6 +43,20 @@ void CAnimatedModelProvider::setDevice(IGXDevice *pDevice) {0, 60, GXDECLTYPE_FLOAT4, GXDECLUSAGE_BLENDWEIGHT}, GX_DECL_END() }; +#endif + + // 52 bytes + GXVertexElement layoutDynamicEx[] = + { + {0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION}, + {0, 12, GXDECLTYPE_FLOAT2, GXDECLUSAGE_TEXCOORD}, + {0, 20, GXDECLTYPE_SHORT4N, GXDECLUSAGE_NORMAL}, + {0, 28, GXDECLTYPE_SHORT4N, GXDECLUSAGE_TANGENT}, + {0, 36, GXDECLTYPE_SHORT4N, GXDECLUSAGE_BINORMAL}, + {0, 44, GXDECLTYPE_UBYTE4, GXDECLUSAGE_BLENDINDICES}, + {0, 48, GXDECLTYPE_UBYTE4N, GXDECLUSAGE_BLENDWEIGHT}, + GX_DECL_END() + }; m_pVertexDeclaration = getDevice()->createVertexDeclaration(layoutDynamicEx); diff --git a/source/anim/AnimatedModelShared.cpp b/source/anim/AnimatedModelShared.cpp index 2fdf6207a84da747dc306f0fe163bb49d09f18a4..44edd18cd25362214bfaa43e4ec1665879f24998 100644 --- a/source/anim/AnimatedModelShared.cpp +++ b/source/anim/AnimatedModelShared.cpp @@ -459,11 +459,11 @@ bool CAnimatedModelShared::init(UINT uResourceCount, IXResourceModelAnimated **p } UINT **ppIndices = new UINT*[m_uLodCount]; - XResourceModelAnimatedVertex **ppVertices = new XResourceModelAnimatedVertex*[m_uLodCount]; + XResourceModelAnimatedVertexGPU **ppVertices = new XResourceModelAnimatedVertexGPU*[m_uLodCount]; for(UINT i = 0; i < m_uLodCount; ++i) { ppIndices[i] = new UINT[aLodIndexCount[i]]; - ppVertices[i] = new XResourceModelAnimatedVertex[aLodVertexCount[i]]; + ppVertices[i] = new XResourceModelAnimatedVertexGPU[aLodVertexCount[i]]; } @@ -494,9 +494,35 @@ bool CAnimatedModelShared::init(UINT uResourceCount, IXResourceModelAnimated **p { // append subset to lod (group by materialId) - //memcpy(&ppIndices[uLod][subset.uStartIndex], pSubset->pIndices, sizeof(UINT) * pSubset->iIndexCount); - memcpy(&ppVertices[uLod][subset.uStartVertex], pSubset->pVertices, sizeof(XResourceModelAnimatedVertex) * pSubset->iVertexCount); + //memcpy(&ppVertices[uLod][subset.uStartVertex], pSubset->pVertices, sizeof(XResourceModelAnimatedVertex) * pSubset->iVertexCount); + for(UINT k = 0; k < pSubset->iVertexCount; ++k) + { +#define TO_SHORT(v) ((short)((v) * 32767.0f)) + auto &dst = (ppVertices[uLod] + subset.uStartVertex)[k]; + auto &src = pSubset->pVertices[k]; + dst.vPos = src.vPos; + dst.vTex = src.vTex; + dst.vNorm[0] = TO_SHORT(src.vNorm.x); + dst.vNorm[1] = TO_SHORT(src.vNorm.y); + dst.vNorm[2] = TO_SHORT(src.vNorm.z); + dst.vTangent[0] = TO_SHORT(src.vTangent.x); + dst.vTangent[1] = TO_SHORT(src.vTangent.y); + dst.vTangent[2] = TO_SHORT(src.vTangent.z); + dst.vBinorm[0] = TO_SHORT(src.vBinorm.x); + dst.vBinorm[1] = TO_SHORT(src.vBinorm.y); + dst.vBinorm[2] = TO_SHORT(src.vBinorm.z); + for(UINT k = 0; k < 4; ++k) + { + dst.u8BoneIndices[k] = src.u8BoneIndices[k]; + } + dst.vBoneWeights[0] = (byte)(src.vBoneWeights.x * 255.0f); + dst.vBoneWeights[1] = (byte)(src.vBoneWeights.y * 255.0f); + dst.vBoneWeights[2] = (byte)(src.vBoneWeights.z * 255.0f); + dst.vBoneWeights[3] = (byte)(src.vBoneWeights.w * 255.0f); +#undef TO_SHORT + } + //memcpy(&ppIndices[uLod][subset.uStartIndex], pSubset->pIndices, sizeof(UINT) * pSubset->iIndexCount); UINT uIndexDelta = aLodVertexCount[uLod]; for(UINT j = 0; j < pSubset->iIndexCount; ++j) { @@ -506,7 +532,7 @@ bool CAnimatedModelShared::init(UINT uResourceCount, IXResourceModelAnimated **p //@TODO: optimize that!!! for(UINT j = 0; j < pSubset->iVertexCount; ++j) { - XResourceModelAnimatedVertex &vtx = ppVertices[uLod][subset.uStartVertex + j]; + XResourceModelAnimatedVertexGPU &vtx = ppVertices[uLod][subset.uStartVertex + j]; for(UINT k = 0; k < 4; ++k) { vtx.u8BoneIndices[k] = getBoneId(aSubsets[i].pResource->getBoneName(vtx.u8BoneIndices[k])); @@ -546,7 +572,7 @@ bool CAnimatedModelShared::init(UINT uResourceCount, IXResourceModelAnimated **p if(m_pProvider->getCore()->isOnMainThread()) { m_ppIndexBuffer[i] = m_pDevice->createIndexBuffer(sizeof(UINT) * aLodIndexCount[i], GXBUFFER_USAGE_STATIC, GXIT_UINT32, ppIndices[i]); - IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelAnimatedVertex) * aLodVertexCount[i], GXBUFFER_USAGE_STATIC, ppVertices[i]); + IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelAnimatedVertexGPU) * aLodVertexCount[i], GXBUFFER_USAGE_STATIC, ppVertices[i]); m_ppRenderBuffer[i] = m_pDevice->createRenderBuffer(1, &pVertexBuffer, m_pProvider->getVertexDeclaration()); mem_release(pVertexBuffer); } @@ -680,7 +706,7 @@ void CAnimatedModelShared::initGPUresources() for(UINT i = 0; i < m_uLodCount; ++i) { m_ppIndexBuffer[i] = m_pDevice->createIndexBuffer(sizeof(UINT) * m_puTempTotalIndices[i], GXBUFFER_USAGE_STATIC, GXIT_UINT32, m_ppTempIndices[i]); - IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelAnimatedVertex) * m_puTempTotalVertices[i], GXBUFFER_USAGE_STATIC, m_ppTempVertices[i]); + IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelAnimatedVertexGPU) * m_puTempTotalVertices[i], GXBUFFER_USAGE_STATIC, m_ppTempVertices[i]); m_ppRenderBuffer[i] = m_pDevice->createRenderBuffer(1, &pVertexBuffer, m_pProvider->getVertexDeclaration()); mem_release(pVertexBuffer); diff --git a/source/anim/AnimatedModelShared.h b/source/anim/AnimatedModelShared.h index f8e84fee27c2e7b24d438bbe9ca4191bddab99cf..9c67a14046990f53cf66ce689f34f7d2a10bbf6d 100644 --- a/source/anim/AnimatedModelShared.h +++ b/source/anim/AnimatedModelShared.h @@ -72,7 +72,7 @@ protected: IGXIndexBuffer **m_ppIndexBuffer = NULL; UINT **m_ppTempIndices = NULL; - XResourceModelAnimatedVertex **m_ppTempVertices = NULL; + XResourceModelAnimatedVertexGPU **m_ppTempVertices = NULL; UINT *m_puTempTotalIndices = 0; UINT *m_puTempTotalVertices = 0; diff --git a/source/anim/DynamicModelProvider.cpp b/source/anim/DynamicModelProvider.cpp index 2d3fe536beb2540d0329edaa5a222e7bf6f1858b..98c6715f262f65fe0468807e7d3b54d154622fea 100644 --- a/source/anim/DynamicModelProvider.cpp +++ b/source/anim/DynamicModelProvider.cpp @@ -209,7 +209,8 @@ void CDynamicModelProvider::setDevice(IGXDevice *pDevice) { m_pRenderContext = pDevice; - +#if 0 + // 56 bytes GXVertexElement layoutStaticEx[] = { {0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION}, @@ -219,6 +220,17 @@ void CDynamicModelProvider::setDevice(IGXDevice *pDevice) {0, 44, GXDECLTYPE_FLOAT3, GXDECLUSAGE_BINORMAL}, GX_DECL_END() }; +#endif + // 40 bytes/ 28? + GXVertexElement layoutStaticEx[] = + { + {0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION}, + {0, 12, GXDECLTYPE_FLOAT2, GXDECLUSAGE_TEXCOORD}, + {0, 20, GXDECLTYPE_SHORT4N, GXDECLUSAGE_NORMAL}, + {0, 28, GXDECLTYPE_SHORT4N, GXDECLUSAGE_TANGENT}, + {0, 36, GXDECLTYPE_SHORT4N, GXDECLUSAGE_BINORMAL}, + GX_DECL_END() + }; m_pVertexDeclaration = pDevice->createVertexDeclaration(layoutStaticEx); diff --git a/source/anim/DynamicModelShared.cpp b/source/anim/DynamicModelShared.cpp index 0216f5d03fbf0fd774c6b159872a853eb0be9020..f4444d79885e1c5def83c16ed7893222677a825e 100644 --- a/source/anim/DynamicModelShared.cpp +++ b/source/anim/DynamicModelShared.cpp @@ -138,7 +138,7 @@ bool CDynamicModelShared::init(IXResourceModelStatic *pResource) if(!m_pProvider->getCore()->isOnMainThread()) { m_ppTempIndices = new UINT*[uLodCount]; - m_ppTempVertices = new XResourceModelStaticVertex*[uLodCount]; + m_ppTempVertices = new XResourceModelStaticVertexGPU*[uLodCount]; m_puTempTotalIndices = new UINT[uLodCount]; m_puTempTotalVertices = new UINT[uLodCount]; } @@ -157,7 +157,7 @@ bool CDynamicModelShared::init(IXResourceModelStatic *pResource) uTotalVertices += pSubset->iVertexCount; } - XResourceModelStaticVertex *pVertices = new XResourceModelStaticVertex[uTotalVertices]; + XResourceModelStaticVertexGPU *pVertices = new XResourceModelStaticVertexGPU[uTotalVertices]; UINT *pIndices = new UINT[uTotalIndices]; subset_t subset; @@ -174,7 +174,25 @@ bool CDynamicModelShared::init(IXResourceModelStatic *pResource) subset.uIndexCount = pSubset->iIndexCount; subset.uVertexCount = pSubset->iVertexCount; - memcpy(pVertices + subset.uStartVertex, pSubset->pVertices, sizeof(XResourceModelStaticVertex) * pSubset->iVertexCount); + //memcpy(pVertices + subset.uStartVertex, pSubset->pVertices, sizeof(XResourceModelStaticVertex) * pSubset->iVertexCount); + for(UINT k = 0; k < pSubset->iVertexCount; ++k) + { +#define TO_SHORT(v) ((short)((v) * 32767.0f)) + auto &dst = (pVertices + subset.uStartVertex)[k]; + auto &src = pSubset->pVertices[k]; + dst.vPos = src.vPos; + dst.vTex = src.vTex; + dst.vNorm[0] = TO_SHORT(src.vNorm.x); + dst.vNorm[1] = TO_SHORT(src.vNorm.y); + dst.vNorm[2] = TO_SHORT(src.vNorm.z); + dst.vTangent[0] = TO_SHORT(src.vTangent.x); + dst.vTangent[1] = TO_SHORT(src.vTangent.y); + dst.vTangent[2] = TO_SHORT(src.vTangent.z); + dst.vBinorm[0] = TO_SHORT(src.vBinorm.x); + dst.vBinorm[1] = TO_SHORT(src.vBinorm.y); + dst.vBinorm[2] = TO_SHORT(src.vBinorm.z); +#undef TO_SHORT + } memcpy(pIndices + subset.uStartIndex, pSubset->pIndices, sizeof(UINT) * pSubset->iIndexCount); m_aLods[i][uMaterial] = subset; @@ -204,7 +222,7 @@ bool CDynamicModelShared::init(IXResourceModelStatic *pResource) if(m_pProvider->getCore()->isOnMainThread()) { m_ppIndexBuffer[i] = m_pDevice->createIndexBuffer(sizeof(UINT) * uTotalIndices, GXBUFFER_USAGE_STATIC, GXIT_UINT32, pIndices); - IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelStaticVertex) * uTotalVertices, GXBUFFER_USAGE_STATIC, pVertices); + IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelStaticVertexGPU) * uTotalVertices, GXBUFFER_USAGE_STATIC, pVertices); m_ppRenderBuffer[i] = m_pDevice->createRenderBuffer(1, &pVertexBuffer, m_pProvider->getVertexDeclaration()); mem_release(pVertexBuffer); @@ -358,7 +376,7 @@ void CDynamicModelShared::initGPUresources() for(UINT i = 0, l = m_aLods.size(); i < l; ++i) { m_ppIndexBuffer[i] = m_pDevice->createIndexBuffer(sizeof(UINT) * m_puTempTotalIndices[i], GXBUFFER_USAGE_STATIC, GXIT_UINT32, m_ppTempIndices[i]); - IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelStaticVertex) * m_puTempTotalVertices[i], GXBUFFER_USAGE_STATIC, m_ppTempVertices[i]); + IGXVertexBuffer *pVertexBuffer = m_pDevice->createVertexBuffer(sizeof(XResourceModelStaticVertexGPU) * m_puTempTotalVertices[i], GXBUFFER_USAGE_STATIC, m_ppTempVertices[i]); m_ppRenderBuffer[i] = m_pDevice->createRenderBuffer(1, &pVertexBuffer, m_pProvider->getVertexDeclaration()); mem_release(pVertexBuffer); diff --git a/source/anim/DynamicModelShared.h b/source/anim/DynamicModelShared.h index 0fba2c613fdcd7e7ea342d778094dc3a1e831434..92ee37785716f49b82180caea14910d4ae98e861 100644 --- a/source/anim/DynamicModelShared.h +++ b/source/anim/DynamicModelShared.h @@ -63,7 +63,7 @@ protected: IGXIndexBuffer **m_ppIndexBuffer = NULL; UINT **m_ppTempIndices = NULL; - XResourceModelStaticVertex **m_ppTempVertices = NULL; + XResourceModelStaticVertexGPU **m_ppTempVertices = NULL; UINT *m_puTempTotalIndices = 0; UINT *m_puTempTotalVertices = 0; diff --git a/source/xcommon/resource/IXResourceModel.h b/source/xcommon/resource/IXResourceModel.h index 0ed5a3925627406d5dc94956c21c2a80a4d38bde..b8f83caa97b989948dfd99766aeeb3697e961f1c 100644 --- a/source/xcommon/resource/IXResourceModel.h +++ b/source/xcommon/resource/IXResourceModel.h @@ -98,6 +98,15 @@ struct XResourceModelStaticVertex float3_t vBinorm; /*!< Бинормаль */ }; +struct XResourceModelStaticVertexGPU +{ + float3_t vPos; /*!< Позиция */ + float2_t vTex; /*!< Текстурные координаты */ + short vNorm[4]; /*!< Нормаль */ + short vTangent[4]; /*!< Тангент */ + short vBinorm[4]; /*!< Бинормаль */ +}; + struct XResourceModelStaticSubset { uint32_t iMaterialID = 0; //!< Идентификатор материала @@ -118,6 +127,17 @@ struct XResourceModelAnimatedVertex float4_t vBoneWeights; /*!< Веса костей */ }; +struct XResourceModelAnimatedVertexGPU +{ + float3_t vPos; /*!< Позиция */ + float2_t vTex; /*!< Текстурные координаты */ + short vNorm[4]; /*!< Нормаль */ + short vTangent[4]; /*!< Тангент */ + short vBinorm[4]; /*!< Бинормаль */ + byte u8BoneIndices[4]; /*!< Индексы костей */ + byte vBoneWeights[4]; /*!< Веса костей */ +}; + struct XResourceModelAnimatedSubset { uint32_t iMaterialID = 0; //!< Идентификатор материала