From db6263cb536eef6def628434fba8b448e8550937 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Mon, 2 Oct 2023 11:32:18 +0800 Subject: [PATCH] finish CKMaterial writer. add lost SetClassId for each writer --- LibCmo/CK2/ObjImpls/CK3dEntity.cpp | 1 + LibCmo/CK2/ObjImpls/CKBeObject.cpp | 3 +- LibCmo/CK2/ObjImpls/CKGroup.cpp | 3 +- LibCmo/CK2/ObjImpls/CKMaterial.cpp | 92 ++++++++++++++++++++++++++++-- LibCmo/CK2/ObjImpls/CKMesh.cpp | 1 + LibCmo/CK2/ObjImpls/CKObject.cpp | 1 + 6 files changed, 93 insertions(+), 8 deletions(-) diff --git a/LibCmo/CK2/ObjImpls/CK3dEntity.cpp b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp index f988e0b..dd16046 100644 --- a/LibCmo/CK2/ObjImpls/CK3dEntity.cpp +++ b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp @@ -85,6 +85,7 @@ namespace LibCmo::CK2::ObjImpls { } + chunk->SetClassId(CK_CLASSID::CKCID_3DENTITY); return true; } diff --git a/LibCmo/CK2/ObjImpls/CKBeObject.cpp b/LibCmo/CK2/ObjImpls/CKBeObject.cpp index dbde0bd..8d377b2 100644 --- a/LibCmo/CK2/ObjImpls/CKBeObject.cpp +++ b/LibCmo/CK2/ObjImpls/CKBeObject.cpp @@ -15,7 +15,8 @@ namespace LibCmo::CK2::ObjImpls { bool CKBeObject::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { bool suc = CKSceneObject::Save(chunk, file, flags); if (!suc) return false; - + + chunk->SetClassId(CK_CLASSID::CKCID_BEOBJECT); return true; } diff --git a/LibCmo/CK2/ObjImpls/CKGroup.cpp b/LibCmo/CK2/ObjImpls/CKGroup.cpp index be4016e..17bb0b7 100644 --- a/LibCmo/CK2/ObjImpls/CKGroup.cpp +++ b/LibCmo/CK2/ObjImpls/CKGroup.cpp @@ -36,7 +36,8 @@ namespace LibCmo::CK2::ObjImpls { bool CKGroup::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { bool suc = CKBeObject::Save(chunk, file, flags); if (!suc) return false; - + + chunk->SetClassId(CK_CLASSID::CKCID_GROUP); return true; } diff --git a/LibCmo/CK2/ObjImpls/CKMaterial.cpp b/LibCmo/CK2/ObjImpls/CKMaterial.cpp index d222cb2..5c2f43b 100644 --- a/LibCmo/CK2/ObjImpls/CKMaterial.cpp +++ b/LibCmo/CK2/ObjImpls/CKMaterial.cpp @@ -47,7 +47,91 @@ namespace LibCmo::CK2::ObjImpls { bool CKMaterial::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { bool suc = CKBeObject::Save(chunk, file, flags); if (!suc) return false; + + // save main data + { + chunk->WriteIdentifier(CK_STATESAVEFLAGS_MATERIAL::CK_STATESAVE_MATDATA); + // 4 basic color and some power + CKDWORD col; + col = m_Diffuse.ToARGB(); + chunk->WriteStruct(col); + col = m_Ambient.ToARGB(); + chunk->WriteStruct(col); + col = m_Specular.ToARGB(); + chunk->WriteStruct(col); + col = m_Emissive.ToARGB(); + chunk->WriteStruct(col); + + chunk->WriteStruct(m_SpecularPower); + + // write main texture + chunk->WriteObjectPointer(m_Textures[0]); + + // misc data + chunk->WriteStruct(m_TextureBorderColor); + + // write mix data 1 + // construct mix data, see Read for more info about this mix data + CKDWORD mixdata = 0; + mixdata |= static_cast(m_TextureAddressMode) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_FillMode) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_ShadeMode) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_DestBlend) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_SourceBlend) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_TextureMagMode) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_TextureMinMode) & 0xF; + mixdata <<= 4; + mixdata |= static_cast(m_TextureBlendMode) & 0xF; + // write it + chunk->WriteStruct(mixdata); + + // write mix data 2 + // construct it first, see Read for more info about this mix data + mixdata = 0; + mixdata |= static_cast(m_AlphaRef) & 0xFF; + mixdata <<= 8; + mixdata |= static_cast(m_AlphaFunc) & 0xFF; + mixdata <<= 8; + mixdata |= static_cast(m_ZFunc) & 0xFF; + mixdata <<= 8; + // sub mix flags + CKDWORD mixflags = 0; + if (m_EnableTwoSided) mixflags |= 0b1; + if (m_EnableZWrite) mixflags |= 0b10; + if (m_EnablePerspectiveCorrection) mixflags |= 0b100; + if (m_EnableAlphaBlend) mixflags |= 0b1000; + if (m_EnableAlphaTest) mixflags |= 0b10000; + // merge into mix data + mixdata |= mixflags & 0xFF; + // write it + chunk->WriteStruct(mixdata); + + } + + // write effect and extra texture. + // it seems that extra textures only available when a valid effect existing + if (m_Effect != VxMath::VX_EFFECT::VXEFFECT_NONE) { + // we only support no-parameter effect, write it + chunk->WriteIdentifier(CK_STATESAVEFLAGS_MATERIAL::CK_STATESAVE_MATDATA3); + chunk->WriteStruct(m_Effect); + + // if have extra textures, write it + if (m_Textures[1] != nullptr || m_Textures[2] != nullptr || m_Textures[3] != nullptr) { + chunk->WriteIdentifier(CK_STATESAVEFLAGS_MATERIAL::CK_STATESAVE_MATDATA2); + chunk->WriteObjectPointer(m_Textures[1]); + chunk->WriteObjectPointer(m_Textures[2]); + chunk->WriteObjectPointer(m_Textures[3]); + } + } + + chunk->SetClassId(CK_CLASSID::CKCID_MATERIAL); return true; } @@ -147,9 +231,7 @@ namespace LibCmo::CK2::ObjImpls { // single effect if (chunk->SeekIdentifier(CK_STATESAVEFLAGS_MATERIAL::CK_STATESAVE_MATDATA3)) { - CKDWORD data; - chunk->ReadStruct(data); - m_Effect = static_cast(data); + chunk->ReadStruct(m_Effect); } // effect with parameter @@ -163,9 +245,7 @@ namespace LibCmo::CK2::ObjImpls { chunk->ReadObjectID(paramid); // read effect self - CKDWORD data; - chunk->ReadStruct(data); - m_Effect = static_cast(data); + chunk->ReadStruct(m_Effect); } return true; diff --git a/LibCmo/CK2/ObjImpls/CKMesh.cpp b/LibCmo/CK2/ObjImpls/CKMesh.cpp index 8c49e02..f2a5ce8 100644 --- a/LibCmo/CK2/ObjImpls/CKMesh.cpp +++ b/LibCmo/CK2/ObjImpls/CKMesh.cpp @@ -197,6 +197,7 @@ namespace LibCmo::CK2::ObjImpls { } + chunk->SetClassId(CK_CLASSID::CKCID_MESH); return true; } diff --git a/LibCmo/CK2/ObjImpls/CKObject.cpp b/LibCmo/CK2/ObjImpls/CKObject.cpp index 344b030..2afbb00 100644 --- a/LibCmo/CK2/ObjImpls/CKObject.cpp +++ b/LibCmo/CK2/ObjImpls/CKObject.cpp @@ -56,6 +56,7 @@ namespace LibCmo::CK2::ObjImpls { chunk->WriteIdentifier(CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN); } + chunk->SetClassId(CK_CLASSID::CKCID_OBJECT); return true; }