mirror of https://github.com/AxioDL/metaforce.git
Tons of PART rendering preparation
This commit is contained in:
parent
0260ebcd64
commit
a80142728d
|
@ -42,7 +42,7 @@ static inline uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y)
|
|||
int ry = y % 8;
|
||||
int bidx = by * bwidth + bx;
|
||||
const uint8_t* btexels = &texels[32*bidx];
|
||||
return btexels[ry*4+rx/2] >> ((rx%2)?0:4) & 0xf;
|
||||
return btexels[ry*4+rx/2] >> ((rx&1)?0:4) & 0xf;
|
||||
}
|
||||
|
||||
static inline uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y)
|
||||
|
|
|
@ -43,6 +43,7 @@ add_executable(urde WIN32 MACOSX_BUNDLE
|
|||
ParticleEditor.hpp ParticleEditor.cpp atdna_ParticleEditor.cpp
|
||||
InformationCenter.hpp InformationCenter.hpp atdna_InformationCenter.cpp
|
||||
ProjectManager.hpp ProjectManager.cpp
|
||||
ProjectResourceFactory.hpp ProjectResourceFactory.cpp
|
||||
ViewManager.hpp ViewManager.cpp
|
||||
Resource.hpp Resource.cpp
|
||||
Camera.hpp Camera.cpp)
|
||||
|
|
|
@ -6,9 +6,22 @@ namespace URDE
|
|||
{
|
||||
static LogVisor::LogModule Log("URDE::ProjectManager");
|
||||
|
||||
void ProjectManager::IndexMP1Resources()
|
||||
{
|
||||
const std::vector<HECL::Database::Project::ProjectDataSpec>& specs = m_proj->getDataSpecs();
|
||||
for (const HECL::Database::Project::ProjectDataSpec& spec : m_proj->getDataSpecs())
|
||||
{
|
||||
if (&spec.spec == &DataSpec::SpecEntMP1)
|
||||
{
|
||||
m_factory.BuildObjectMap(spec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ProjectManager::m_registeredSpecs = false;
|
||||
ProjectManager::ProjectManager(ViewManager &vm)
|
||||
: m_vm(vm)
|
||||
: m_vm(vm), m_objStore(m_factory)
|
||||
{
|
||||
if (!m_registeredSpecs)
|
||||
{
|
||||
|
@ -96,6 +109,8 @@ bool ProjectManager::openProject(const HECL::SystemString& path)
|
|||
|
||||
#endif
|
||||
|
||||
IndexMP1Resources();
|
||||
m_vm.BuildTestPART(m_objStore);
|
||||
m_vm.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
|
||||
m_vm.DismissSplash();
|
||||
m_vm.FadeInEditors();
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <HECL/Database.hpp>
|
||||
#include <Athena/DNAYaml.hpp>
|
||||
#include "ProjectResourceFactory.hpp"
|
||||
#include "Runtime/CSimplePool.hpp"
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
|
@ -21,6 +23,11 @@ class ProjectManager
|
|||
ViewManager& m_vm;
|
||||
std::unique_ptr<HECL::Database::Project> m_proj;
|
||||
static bool m_registeredSpecs;
|
||||
ProjectResourceFactory m_factory;
|
||||
pshag::CSimplePool m_objStore;
|
||||
|
||||
void IndexMP1Resources();
|
||||
|
||||
public:
|
||||
ProjectManager(ViewManager& vm);
|
||||
operator bool() const {return m_proj.operator bool();}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#include "ProjectResourceFactory.hpp"
|
||||
#include "Runtime/IOStreams.hpp"
|
||||
|
||||
#include "Runtime/Particle/CParticleDataFactory.hpp"
|
||||
#include "Runtime/CTexture.hpp"
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
|
||||
ProjectResourceFactory::ProjectResourceFactory()
|
||||
{
|
||||
m_factoryMgr.AddFactory(HECL::FOURCC('TXTR'), pshag::FTextureFactory);
|
||||
m_factoryMgr.AddFactory(HECL::FOURCC('PART'), pshag::FParticleFactory);
|
||||
}
|
||||
|
||||
void ProjectResourceFactory::RecursiveAddDirObjects(const HECL::ProjectPath& path)
|
||||
{
|
||||
HECL::DirectoryEnumerator de = path.enumerateDir();
|
||||
for (const HECL::DirectoryEnumerator::Entry& ent : de)
|
||||
{
|
||||
if (ent.m_isDir)
|
||||
RecursiveAddDirObjects(HECL::ProjectPath(path, ent.m_name));
|
||||
if (ent.m_name.size() == 13 && ent.m_name[4] == _S('_'))
|
||||
{
|
||||
HECL::SystemUTF8View entu8(ent.m_name);
|
||||
u32 id = strtoul(entu8.c_str() + 5, nullptr, 16);
|
||||
if (id)
|
||||
{
|
||||
pshag::SObjectTag objTag = {HECL::FourCC(entu8.c_str()), id};
|
||||
if (m_resPaths.find(objTag) == m_resPaths.end())
|
||||
m_resPaths[objTag] = HECL::ProjectPath(path, ent.m_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectResourceFactory::BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec)
|
||||
{
|
||||
m_resPaths.clear();
|
||||
RecursiveAddDirObjects(spec.cookedPath);
|
||||
}
|
||||
|
||||
std::unique_ptr<pshag::IObj> ProjectResourceFactory::Build(const pshag::SObjectTag& tag,
|
||||
const pshag::CVParamTransfer& paramXfer)
|
||||
{
|
||||
auto search = m_resPaths.find(tag);
|
||||
if (search == m_resPaths.end())
|
||||
return {};
|
||||
|
||||
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
|
||||
if (fr.hasError())
|
||||
return {};
|
||||
|
||||
return m_factoryMgr.MakeObject(tag, fr, paramXfer);
|
||||
}
|
||||
|
||||
void ProjectResourceFactory::BuildAsync(const pshag::SObjectTag& tag,
|
||||
const pshag::CVParamTransfer& paramXfer,
|
||||
pshag::IObj** objOut)
|
||||
{
|
||||
std::unique_ptr<pshag::IObj> obj = Build(tag, paramXfer);
|
||||
*objOut = obj.release();
|
||||
}
|
||||
|
||||
void ProjectResourceFactory::CancelBuild(const pshag::SObjectTag&)
|
||||
{
|
||||
}
|
||||
|
||||
bool ProjectResourceFactory::CanBuild(const pshag::SObjectTag& tag)
|
||||
{
|
||||
auto search = m_resPaths.find(tag);
|
||||
if (search == m_resPaths.end())
|
||||
return false;
|
||||
|
||||
Athena::io::FileReader fr(search->second.getAbsolutePath(), 32 * 1024, false);
|
||||
if (fr.hasError())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const pshag::SObjectTag* ProjectResourceFactory::GetResourceIdByName(const char*) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef URDE_PROJECT_RESOURCE_FACTORY_HPP
|
||||
#define URDE_PROJECT_RESOURCE_FACTORY_HPP
|
||||
|
||||
#include "Runtime/IFactory.hpp"
|
||||
#include "Runtime/CFactoryMgr.hpp"
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
|
||||
class ProjectResourceFactory : public pshag::IFactory
|
||||
{
|
||||
std::unordered_map<pshag::SObjectTag, HECL::ProjectPath> m_resPaths;
|
||||
pshag::CFactoryMgr m_factoryMgr;
|
||||
void RecursiveAddDirObjects(const HECL::ProjectPath& path);
|
||||
public:
|
||||
ProjectResourceFactory();
|
||||
void BuildObjectMap(const HECL::Database::Project::ProjectDataSpec& spec);
|
||||
|
||||
std::unique_ptr<pshag::IObj> Build(const pshag::SObjectTag&, const pshag::CVParamTransfer&);
|
||||
void BuildAsync(const pshag::SObjectTag&, const pshag::CVParamTransfer&, pshag::IObj**);
|
||||
void CancelBuild(const pshag::SObjectTag&);
|
||||
bool CanBuild(const pshag::SObjectTag&);
|
||||
const pshag::SObjectTag* GetResourceIdByName(const char*) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // URDE_PROJECT_RESOURCE_FACTORY_HPP
|
|
@ -76,6 +76,16 @@ void ViewManager::DismissSplash()
|
|||
m_splash->close();
|
||||
}
|
||||
|
||||
void ViewManager::BuildTestPART(pshag::IObjectStore& objStore)
|
||||
{
|
||||
m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x0B4D0FBF});
|
||||
m_partGen.reset(new pshag::CElementGen(m_partGenDesc,
|
||||
pshag::CElementGen::EModelOrientationType::Normal,
|
||||
pshag::CElementGen::EOptionalSystemFlags::None));
|
||||
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
|
||||
m_rootView->accessContentViews().push_back(m_particleView.get());
|
||||
}
|
||||
|
||||
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
||||
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
|
||||
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish()),
|
||||
|
@ -168,6 +178,9 @@ void ViewManager::init(boo::IApplication* app)
|
|||
root->updateSize();
|
||||
|
||||
m_mainWindow->setWaitCursor(false);
|
||||
|
||||
pshag::CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue());
|
||||
pshag::CElementGen::Initialize();
|
||||
}
|
||||
|
||||
bool ViewManager::proc()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "ProjectManager.hpp"
|
||||
#include "Space.hpp"
|
||||
|
||||
#include "Runtime/Particle/CElementGen.hpp"
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
class SplashScreen;
|
||||
|
@ -31,6 +33,31 @@ class ViewManager : public Specter::IViewManager
|
|||
std::unique_ptr<RootSpace> m_rootSpace;
|
||||
Specter::View* m_rootSpaceView = nullptr;
|
||||
|
||||
class ParticleView : public Specter::View
|
||||
{
|
||||
ViewManager& m_vm;
|
||||
public:
|
||||
ParticleView(ViewManager& vm, Specter::ViewResources& res, Specter::View& parent)
|
||||
: View(res, parent), m_vm(vm) {}
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
if (m_vm.m_partGen)
|
||||
{
|
||||
m_vm.m_partGen->Update(1.0 / 60.0);
|
||||
pshag::CGraphics::SetModelMatrix(Zeus::CTransform::Identity());
|
||||
pshag::CGraphics::SetViewPointMatrix(Zeus::CTransform::Identity() + Zeus::CVector3f(0.f, -10.f, 0.f));
|
||||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||
pshag::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||
gfxQ->clearTarget(false, true);
|
||||
m_vm.m_partGen->Render();
|
||||
}
|
||||
}
|
||||
};
|
||||
std::unique_ptr<ParticleView> m_particleView;
|
||||
pshag::TLockedToken<pshag::CGenDescription> m_partGenDesc;
|
||||
std::unique_ptr<pshag::CElementGen> m_partGen;
|
||||
|
||||
HECL::SystemString m_recentProjectsPath;
|
||||
std::vector<HECL::SystemString> m_recentProjects;
|
||||
HECL::SystemString m_recentFilesPath;
|
||||
|
@ -53,6 +80,8 @@ class ViewManager : public Specter::IViewManager
|
|||
unsigned m_editorFrames = 120;
|
||||
void FadeInEditors() {m_editorFrames = 0;}
|
||||
|
||||
void BuildTestPART(pshag::IObjectStore& objStore);
|
||||
|
||||
Space* m_deferSplit = nullptr;
|
||||
Specter::SplitView::Axis m_deferSplitAxis;
|
||||
int m_deferSplitThisSlot;
|
||||
|
|
|
@ -29,7 +29,7 @@ boo::GraphicsDataToken InitializeIcons(Specter::ViewResources& viewRes)
|
|||
Log.report(LogVisor::FatalError, "unable to decompress icons");
|
||||
|
||||
g_IconAtlas.initializeAtlas(viewRes.m_factory->newStaticTexture(width, height, mips, boo::TextureFormat::RGBA8,
|
||||
std::move(texels), destSz));
|
||||
texels.get(), destSz));
|
||||
return viewRes.m_factory->commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ struct Application : boo::IApplicationCallback
|
|||
|
||||
int appMain(boo::IApplication* app)
|
||||
{
|
||||
pshag::CElementGen::Initialize();
|
||||
m_viewManager.init(app);
|
||||
while (m_running)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#include "CFactoryMgr.hpp"
|
||||
#include "IObj.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
|
||||
CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, pshag::CInputStream& in,
|
||||
const CVParamTransfer& paramXfer)
|
||||
{
|
||||
auto search = m_factories.find(tag.type);
|
||||
if (search == m_factories.end())
|
||||
return {};
|
||||
|
||||
return search->second(tag, in, paramXfer);
|
||||
}
|
||||
|
||||
CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, void* buf, int size,
|
||||
bool compressed, const CVParamTransfer& paramXfer)
|
||||
{
|
||||
auto search = m_factories.find(tag.type);
|
||||
if (search == m_factories.end())
|
||||
return {};
|
||||
|
||||
if (compressed)
|
||||
{
|
||||
CZipInputStream r(std::make_unique<Athena::io::MemoryReader>(buf, size));
|
||||
return search->second(tag, r, paramXfer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Athena::io::MemoryReader r(buf, size);
|
||||
return search->second(tag, r, paramXfer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,21 +3,27 @@
|
|||
|
||||
#include <unordered_map>
|
||||
#include "RetroTypes.hpp"
|
||||
#include "IOStreams.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
class SObjectTag;
|
||||
class CVParamTransfer;
|
||||
class CInputStream;
|
||||
|
||||
typedef void(*CFactoryFnReturn)(const SObjectTag&, CInputStream&, const CVParamTransfer&);
|
||||
class IObj;
|
||||
|
||||
using CFactoryFnReturn = std::unique_ptr<IObj>;
|
||||
using FFactoryFunc = std::function<CFactoryFnReturn(const pshag::SObjectTag& tag,
|
||||
pshag::CInputStream& in,
|
||||
const pshag::CVParamTransfer& vparms)>;
|
||||
class CFactoryMgr
|
||||
{
|
||||
std::unordered_map<u32, CFactoryFnReturn> m_factories;
|
||||
std::unordered_map<FourCC, FFactoryFunc> m_factories;
|
||||
public:
|
||||
MakeObjectFromMemory(const SObjectTag&, void*, int, bool, const CVParamTransfer&);
|
||||
void AddFactory(FourCC key, CFactoryFnReturn func)
|
||||
CFactoryFnReturn MakeObject(const SObjectTag& tag, pshag::CInputStream& in,
|
||||
const CVParamTransfer& paramXfer);
|
||||
CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, void* buf, int size, bool compressed,
|
||||
const CVParamTransfer& paramXfer);
|
||||
void AddFactory(FourCC key, FFactoryFunc func)
|
||||
{
|
||||
m_factories[key] = func;
|
||||
}
|
||||
|
|
|
@ -121,6 +121,17 @@ struct SClipScreenRect
|
|||
|
||||
enum class ETexelFormat
|
||||
{
|
||||
I4 = 0,
|
||||
I8 = 1,
|
||||
IA4 = 2,
|
||||
IA8 = 3,
|
||||
C4 = 4,
|
||||
C8 = 5,
|
||||
C14X2 = 6,
|
||||
RGB565 = 7,
|
||||
RGB5A3 = 8,
|
||||
RGBA8 = 9,
|
||||
CMPR = 10
|
||||
};
|
||||
|
||||
class CGraphics
|
||||
|
@ -163,7 +174,7 @@ public:
|
|||
static Zeus::CMatrix4f GetPerspectiveProjectionMatrix();
|
||||
static const CProjectionState& GetProjectionState();
|
||||
static void SetProjectionState(const CProjectionState&);
|
||||
static void SetPerspective(float, float, float, float);
|
||||
static void SetPerspective(float fovy, float aspect, float near, float far);
|
||||
static void FlushProjection();
|
||||
static Zeus::CVector2i ProjectPoint(const Zeus::CVector3f& point);
|
||||
static SClipScreenRect ClipScreenRectFromMS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
|
||||
|
@ -173,6 +184,12 @@ public:
|
|||
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
|
||||
static boo::ITextureR* g_SpareTexture;
|
||||
|
||||
static void InitializeBoo(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cc)
|
||||
{
|
||||
g_BooFactory = factory;
|
||||
g_BooMainCommandQueue = cc;
|
||||
}
|
||||
|
||||
static boo::IGraphicsBufferD* NewDynamicGPUBuffer(boo::BufferUse use, size_t stride, size_t count)
|
||||
{
|
||||
return g_BooFactory->newDynamicBuffer(use, stride, count);
|
||||
|
@ -185,8 +202,9 @@ public:
|
|||
{
|
||||
g_BooMainCommandQueue->setShaderDataBinding(binding);
|
||||
}
|
||||
static void DrawInstances(size_t start, size_t count, size_t instCount)
|
||||
static void DrawInstances(boo::Primitive prim, size_t start, size_t count, size_t instCount)
|
||||
{
|
||||
g_BooMainCommandQueue->setDrawPrimitive(prim);
|
||||
g_BooMainCommandQueue->drawInstances(start, count, instCount);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -58,7 +58,7 @@ add_library(RuntimeCommon
|
|||
CPakFile.hpp CPakFile.cpp
|
||||
CStringExtras.hpp
|
||||
CCallStack.hpp
|
||||
CTexture.hpp CTexture.cpp
|
||||
CTexture.hpp CTextureBoo.cpp
|
||||
CLight.hpp CLight.cpp
|
||||
IOStreams.hpp IOStreams.cpp
|
||||
CMainFlowBase.hpp CMainFlowBase.cpp
|
||||
|
|
|
@ -11,7 +11,9 @@ CSimplePool::CSimplePool(IFactory& factory)
|
|||
|
||||
CToken CSimplePool::GetObj(const SObjectTag& tag, const CVParamTransfer& paramXfer)
|
||||
{
|
||||
auto iter = std::find_if(x4_resources.begin(), x4_resources.end(), [&tag](std::pair<SObjectTag, CObjectReference*> pair)->bool{
|
||||
auto iter = std::find_if(x4_resources.begin(), x4_resources.end(),
|
||||
[&tag](std::pair<SObjectTag, CObjectReference*> pair) -> bool
|
||||
{
|
||||
return pair.first == tag;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#include "CTexture.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
|
||||
void CTexture::Load(int slot, EClampMode clamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,28 +2,54 @@
|
|||
#define __PSHAG_CTEXTURE_HPP__
|
||||
|
||||
#include "GCNTypes.hpp"
|
||||
#include "IObj.hpp"
|
||||
#include "IOStreams.hpp"
|
||||
#include "CGraphics.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
class CVParamTransfer;
|
||||
|
||||
class CTexture
|
||||
{
|
||||
ETexelFormat x0_fmt;
|
||||
u16 x4_w;
|
||||
u16 x6_h;
|
||||
u32 x8_mips;
|
||||
boo::GraphicsDataToken m_booToken;
|
||||
boo::ITexture* m_booTex;
|
||||
|
||||
size_t ComputeMippedTexelCount();
|
||||
size_t ComputeMippedBlockCountDXT1();
|
||||
void BuildI4FromGCN(CInputStream& in);
|
||||
void BuildI8FromGCN(CInputStream& in);
|
||||
void BuildIA4FromGCN(CInputStream& in);
|
||||
void BuildIA8FromGCN(CInputStream& in);
|
||||
void BuildC4FromGCN(CInputStream& in);
|
||||
void BuildC8FromGCN(CInputStream& in);
|
||||
void BuildC14X2FromGCN(CInputStream& in);
|
||||
void BuildRGB565FromGCN(CInputStream& in);
|
||||
void BuildRGB5A3FromGCN(CInputStream& in);
|
||||
void BuildRGBA8FromGCN(CInputStream& in);
|
||||
void BuildDXT1FromGCN(CInputStream& in);
|
||||
|
||||
public:
|
||||
CTexture(CInputStream& in);
|
||||
enum class EClampMode
|
||||
{
|
||||
None,
|
||||
One
|
||||
};
|
||||
ETexelFormat GetTexelFormat() const {return x0_fmt;}
|
||||
u16 GetWidth() const {return x4_w;}
|
||||
u16 GetHeight() const {return x6_h;}
|
||||
void Load(int slot, EClampMode clamp);
|
||||
boo::ITexture* GetBooTexture() {return m_booTex;}
|
||||
};
|
||||
|
||||
std::unique_ptr<IObj> FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
|
||||
|
||||
}
|
||||
|
||||
#endif // __PSHAG_CTEXTURE_HPP__
|
||||
|
|
|
@ -0,0 +1,679 @@
|
|||
#include "CTexture.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "CToken.hpp"
|
||||
#include "CGraphics.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
|
||||
/* GX uses this upsampling technique to prevent banding on downsampled texture formats */
|
||||
static inline uint8_t Convert3To8(uint8_t v)
|
||||
{
|
||||
/* Swizzle bits: 00000123 -> 12312312 */
|
||||
return (v << 5) | (v << 2) | (v >> 1);
|
||||
}
|
||||
|
||||
static inline uint8_t Convert4To8(uint8_t v)
|
||||
{
|
||||
/* Swizzle bits: 00001234 -> 12341234 */
|
||||
return (v << 4) | v;
|
||||
}
|
||||
|
||||
static inline uint8_t Convert5To8(uint8_t v)
|
||||
{
|
||||
/* Swizzle bits: 00012345 -> 12345123 */
|
||||
return (v << 3) | (v >> 2);
|
||||
}
|
||||
|
||||
static inline uint8_t Convert6To8(uint8_t v)
|
||||
{
|
||||
/* Swizzle bits: 00123456 -> 12345612 */
|
||||
return (v << 2) | (v >> 4);
|
||||
}
|
||||
|
||||
size_t CTexture::ComputeMippedTexelCount()
|
||||
{
|
||||
size_t w = x4_w;
|
||||
size_t h = x6_h;
|
||||
size_t ret = w * h;
|
||||
for (int i=x8_mips ; i>1 ; --i)
|
||||
{
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
ret += w * h;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t CTexture::ComputeMippedBlockCountDXT1()
|
||||
{
|
||||
size_t w = x4_w / 4;
|
||||
size_t h = x6_h / 4;
|
||||
size_t ret = w * h;
|
||||
for (int i=x8_mips ; i>1 ; --i)
|
||||
{
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
ret += w * h;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct RGBA8
|
||||
{
|
||||
u8 r;
|
||||
u8 g;
|
||||
u8 b;
|
||||
u8 a;
|
||||
};
|
||||
|
||||
void CTexture::BuildI4FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 7) / 8;
|
||||
int bheight = (h + 7) / 8;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 8;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 8;
|
||||
for (int y=0 ; y<8 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[4];
|
||||
in.readBytesToBuf(source, 4);
|
||||
for (int x=0 ; x<8 ; ++x)
|
||||
{
|
||||
target[x].r = Convert4To8(source[x/2] >> ((x&1)?0:4) & 0xf);
|
||||
target[x].g = target[x].r;
|
||||
target[x].b = target[x].r;
|
||||
target[x].a = target[x].r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildI8FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 7) / 8;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 8;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[8];
|
||||
in.readBytesToBuf(source, 8);
|
||||
for (int x=0 ; x<8 ; ++x)
|
||||
{
|
||||
target[x].r = source[x];
|
||||
target[x].g = source[x];
|
||||
target[x].b = source[x];
|
||||
target[x].a = source[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildIA4FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 7) / 8;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 8;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[8];
|
||||
in.readBytesToBuf(source, 8);
|
||||
for (int x=0 ; x<8 ; ++x)
|
||||
{
|
||||
u8 intensity = Convert4To8(source[x] >> 4 & 0xf);
|
||||
target[x].r = intensity;
|
||||
target[x].g = intensity;
|
||||
target[x].b = intensity;
|
||||
target[x].a = Convert4To8(source[x] & 0xf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildIA8FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 3) / 4;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 4;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u16 source[4];
|
||||
in.readBytesToBuf(source, 8);
|
||||
for (int x=0 ; x<4 ; ++x)
|
||||
{
|
||||
u8 intensity = source[x] >> 8;
|
||||
target[x].r = intensity;
|
||||
target[x].g = intensity;
|
||||
target[x].b = intensity;
|
||||
target[x].a = source[x] & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
static std::vector<RGBA8> DecodePalette(int numEntries, CInputStream& in)
|
||||
{
|
||||
std::vector<RGBA8> ret;
|
||||
ret.reserve(numEntries);
|
||||
|
||||
enum class EPaletteType
|
||||
{
|
||||
IA8,
|
||||
RGB565,
|
||||
RGB5A3
|
||||
};
|
||||
|
||||
EPaletteType format = EPaletteType(in.readUint32Big());
|
||||
in.readUint32Big();
|
||||
switch (format)
|
||||
{
|
||||
case EPaletteType::IA8:
|
||||
{
|
||||
for (int e=0 ; e<numEntries ; ++e)
|
||||
{
|
||||
u8 intensity = in.readUByte();
|
||||
u8 alpha = in.readUByte();
|
||||
ret.push_back({intensity, intensity, intensity, alpha});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EPaletteType::RGB565:
|
||||
{
|
||||
for (int e=0 ; e<numEntries ; ++e)
|
||||
{
|
||||
u16 texel = in.readUint16Big();
|
||||
ret.push_back({Convert5To8(texel >> 11 & 0x1f),
|
||||
Convert6To8(texel >> 5 & 0x3f),
|
||||
Convert5To8(texel & 0x1f),
|
||||
0xff});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EPaletteType::RGB5A3:
|
||||
{
|
||||
for (int e=0 ; e<numEntries ; ++e)
|
||||
{
|
||||
u16 texel = in.readUint16Big();
|
||||
if (texel & 0x8000)
|
||||
{
|
||||
ret.push_back({Convert5To8(texel >> 10 & 0x1f),
|
||||
Convert5To8(texel >> 5 & 0x1f),
|
||||
Convert5To8(texel & 0x1f),
|
||||
0xff});
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.push_back({Convert4To8(texel >> 8 & 0xf),
|
||||
Convert4To8(texel >> 4 & 0xf),
|
||||
Convert4To8(texel & 0xf),
|
||||
Convert3To8(texel >> 12 & 0x7)});
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CTexture::BuildC4FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
std::vector<RGBA8> palette = DecodePalette(16, in);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 7) / 8;
|
||||
int bheight = (h + 7) / 8;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 8;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 8;
|
||||
for (int y=0 ; y<8 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[4];
|
||||
in.readBytesToBuf(source, 4);
|
||||
for (int x=0 ; x<8 ; ++x)
|
||||
target[x] = palette[source[x/2] >> ((x&1)?0:4) & 0xf];
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildC8FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
std::vector<RGBA8> palette = DecodePalette(256, in);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 7) / 8;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 8;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[8];
|
||||
in.readBytesToBuf(source, 8);
|
||||
for (int x=0 ; x<8 ; ++x)
|
||||
target[x] = palette[source[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildC14X2FromGCN(CInputStream& in)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CTexture::BuildRGB565FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 3) / 4;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 4;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
for (int x=0 ; x<4 ; ++x)
|
||||
{
|
||||
u16 texel = in.readUint16Big();
|
||||
target[x].r = Convert5To8(texel >> 11 & 0x1f);
|
||||
target[x].g = Convert6To8(texel >> 5 & 0x3f);
|
||||
target[x].b = Convert5To8(texel & 0x1f);
|
||||
target[x].a = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildRGB5A3FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 3) / 4;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 4;
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
for (int x=0 ; x<4 ; ++x)
|
||||
{
|
||||
u16 texel = in.readUint16Big();
|
||||
if (texel & 0x8000)
|
||||
{
|
||||
target[x].r = Convert5To8(texel >> 10 & 0x1f);
|
||||
target[x].g = Convert5To8(texel >> 5 & 0x1f);
|
||||
target[x].b = Convert5To8(texel & 0x1f);
|
||||
target[x].a = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
target[x].r = Convert4To8(texel >> 8 & 0xf);
|
||||
target[x].g = Convert4To8(texel >> 4 & 0xf);
|
||||
target[x].b = Convert4To8(texel & 0xf);
|
||||
target[x].a = Convert3To8(texel >> 12 & 0x7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
void CTexture::BuildRGBA8FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t texelCount = ComputeMippedTexelCount();
|
||||
std::unique_ptr<RGBA8[]> buf(new RGBA8[texelCount]);
|
||||
|
||||
int w = x4_w;
|
||||
int h = x6_h;
|
||||
RGBA8* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 3) / 4;
|
||||
int bheight = (h + 3) / 4;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 4;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 4;
|
||||
for (int c=0 ; c<2 ; ++c)
|
||||
{
|
||||
for (int y=0 ; y<4 ; ++y)
|
||||
{
|
||||
RGBA8* target = targetMip + (baseY + y) * w + baseX;
|
||||
u8 source[8];
|
||||
in.readBytesToBuf(source, 8);
|
||||
for (int x=0 ; x<4 ; ++x)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
target[x].g = source[x*2];
|
||||
target[x].b = source[x*2+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
target[x].a = source[x*2];
|
||||
target[x].r = source[x*2+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
struct DXT1Block
|
||||
{
|
||||
uint16_t color1;
|
||||
uint16_t color2;
|
||||
uint8_t lines[4];
|
||||
};
|
||||
|
||||
void CTexture::BuildDXT1FromGCN(CInputStream& in)
|
||||
{
|
||||
size_t blockCount = ComputeMippedBlockCountDXT1();
|
||||
std::unique_ptr<DXT1Block[]> buf(new DXT1Block[blockCount]);
|
||||
|
||||
int w = x4_w / 4;
|
||||
int h = x6_h / 4;
|
||||
DXT1Block* targetMip = buf.get();
|
||||
for (int mip=0 ; mip<x8_mips ; ++mip)
|
||||
{
|
||||
int bwidth = (w + 1) / 2;
|
||||
int bheight = (h + 1) / 2;
|
||||
for (int by=0 ; by<bheight ; ++by)
|
||||
{
|
||||
int baseY = by * 2;
|
||||
for (int bx=0 ; bx<bwidth ; ++bx)
|
||||
{
|
||||
int baseX = bx * 2;
|
||||
for (int y=0 ; y<2 ; ++y)
|
||||
{
|
||||
DXT1Block* target = targetMip + (baseY + y) * w + baseX;
|
||||
DXT1Block source[2];
|
||||
in.readBytesToBuf(source, 16);
|
||||
for (int x=0 ; x<2 ; ++x)
|
||||
{
|
||||
target[x].color1 = HECL::SBig(source[x].color1);
|
||||
target[x].color2 = HECL::SBig(source[x].color2);
|
||||
target[x].lines[0] = source[x].lines[3];
|
||||
target[x].lines[1] = source[x].lines[2];
|
||||
target[x].lines[2] = source[x].lines[1];
|
||||
target[x].lines[3] = source[x].lines[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::DXT1,
|
||||
buf.get(), blockCount * 8,
|
||||
reinterpret_cast<boo::ITextureS**>(&m_booTex));
|
||||
}
|
||||
|
||||
CTexture::CTexture(CInputStream& in)
|
||||
{
|
||||
x0_fmt = ETexelFormat(in.readUint32Big());
|
||||
x4_w = in.readUint16Big();
|
||||
x6_h = in.readUint16Big();
|
||||
x8_mips = in.readUint32Big();
|
||||
|
||||
switch (x0_fmt)
|
||||
{
|
||||
case ETexelFormat::I4:
|
||||
BuildI4FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::I8:
|
||||
BuildI8FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::IA4:
|
||||
BuildIA4FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::IA8:
|
||||
BuildIA8FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::C4:
|
||||
BuildC4FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::C8:
|
||||
BuildC8FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::C14X2:
|
||||
BuildC14X2FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::RGB565:
|
||||
BuildRGB565FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::RGB5A3:
|
||||
BuildRGB5A3FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::RGBA8:
|
||||
BuildRGBA8FromGCN(in);
|
||||
break;
|
||||
case ETexelFormat::CMPR:
|
||||
BuildDXT1FromGCN(in);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CTexture::Load(int slot, EClampMode clamp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<IObj> FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
|
||||
{
|
||||
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(in));
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@ class CVParamTransfer
|
|||
{
|
||||
std::shared_ptr<IVParamObj> m_ref;
|
||||
public:
|
||||
CVParamTransfer();
|
||||
CVParamTransfer() = default;
|
||||
CVParamTransfer(IVParamObj* obj) : m_ref(obj) {}
|
||||
CVParamTransfer(const CVParamTransfer& other) : m_ref(other.m_ref) {}
|
||||
IVParamObj* GetObj() const {return m_ref.get();}
|
||||
|
|
|
@ -54,13 +54,13 @@ class CMain* g_main = nullptr;
|
|||
|
||||
class CGameGlobalObjects
|
||||
{
|
||||
CMemoryCardSys m_memoryCardSys;
|
||||
CResFactory m_resFactory;
|
||||
CSimplePool m_simplePool;
|
||||
CCharacterFactoryBuilder m_charFactoryBuilder;
|
||||
CAiFuncMap m_aiFuncMap;
|
||||
CGameState m_gameState;
|
||||
CInGameTweakManager m_tweakManager;
|
||||
CMemoryCardSys x0_memoryCardSys;
|
||||
CResFactory x20_resFactory;
|
||||
CSimplePool x114_simplePool;
|
||||
CCharacterFactoryBuilder x14c_charFactoryBuilder;
|
||||
CAiFuncMap x188_aiFuncMap;
|
||||
CGameState x1a8_gameState;
|
||||
CInGameTweakManager x1c0_tweakManager;
|
||||
std::unique_ptr<CBooRenderer> m_renderer;
|
||||
|
||||
void AddPaksAndFactories()
|
||||
|
@ -79,22 +79,22 @@ class CGameGlobalObjects
|
|||
|
||||
public:
|
||||
CGameGlobalObjects()
|
||||
: m_simplePool(m_resFactory)
|
||||
: x114_simplePool(x20_resFactory)
|
||||
{
|
||||
g_MemoryCardSys = &m_memoryCardSys;
|
||||
g_ResFactory = &m_resFactory;
|
||||
g_SimplePool = &m_simplePool;
|
||||
g_CharFactoryBuilder = &m_charFactoryBuilder;
|
||||
g_AiFuncMap = &m_aiFuncMap;
|
||||
g_GameState = &m_gameState;
|
||||
g_TweakManager = &m_tweakManager;
|
||||
g_MemoryCardSys = &x0_memoryCardSys;
|
||||
g_ResFactory = &x20_resFactory;
|
||||
g_SimplePool = &x114_simplePool;
|
||||
g_CharFactoryBuilder = &x14c_charFactoryBuilder;
|
||||
g_AiFuncMap = &x188_aiFuncMap;
|
||||
g_GameState = &x1a8_gameState;
|
||||
g_TweakManager = &x1c0_tweakManager;
|
||||
}
|
||||
|
||||
void PostInitialize(CMemorySys& memSys)
|
||||
{
|
||||
AddPaksAndFactories();
|
||||
LoadStringTable();
|
||||
m_renderer.reset(AllocateRenderer(m_simplePool, memSys, m_resFactory));
|
||||
m_renderer.reset(AllocateRenderer(x114_simplePool, memSys, x20_resFactory));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -183,7 +183,7 @@ void CElementGenShaders::Initialize()
|
|||
case boo::IGraphicsDataFactory::Platform::D3D12:
|
||||
m_bindFactory.reset(Initialize(*static_cast<boo::ID3DDataFactory*>(CGraphics::g_BooFactory)));
|
||||
break;
|
||||
#elif __APPLE__
|
||||
#elif BOO_HAS_METAL
|
||||
case boo::IGraphicsDataFactory::Platform::Metal:
|
||||
m_bindFactory.reset(Initialize(*static_cast<boo::MetalDataFactory*>(CGraphics::g_BooFactory)));
|
||||
break;
|
||||
|
@ -1175,6 +1175,7 @@ void CElementGen::Render()
|
|||
|
||||
void CElementGen::RenderModels()
|
||||
{
|
||||
return;
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
|
||||
if (x225_29_modelsUseLights)
|
||||
|
@ -1365,6 +1366,7 @@ void CElementGen::RenderModels()
|
|||
|
||||
void CElementGen::RenderLines()
|
||||
{
|
||||
return;
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
CGlobalRandom gr(x230_randState);
|
||||
|
||||
|
@ -1498,7 +1500,7 @@ void CElementGen::RenderParticles()
|
|||
CUVElement* tind = desc->x58_TIND.get();
|
||||
if (texr && tind)
|
||||
{
|
||||
RenderParticlesIndirectTexture();
|
||||
//RenderParticlesIndirectTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1623,6 +1625,7 @@ void CElementGen::RenderParticles()
|
|||
}
|
||||
|
||||
float size = 0.5f * particle.x2c_lineLengthOrSize;
|
||||
fprintf(stderr, "%p (%f %f %f) %f\n", this, viewPoint.x, viewPoint.y, viewPoint.z, size);
|
||||
if (0.f == particle.x30_lineWidthOrRota)
|
||||
{
|
||||
switch (m_shaderClass)
|
||||
|
@ -1698,11 +1701,11 @@ void CElementGen::RenderParticles()
|
|||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instTexData.size());
|
||||
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instNoTexData.size());
|
||||
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size());
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
@ -1837,11 +1840,11 @@ void CElementGen::RenderParticles()
|
|||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
m_instBuf->load(g_instTexData.data(), g_instTexData.size() * sizeof(SParticleInstanceTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instTexData.size());
|
||||
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instTexData.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
m_instBuf->load(g_instNoTexData.data(), g_instNoTexData.size() * sizeof(SParticleInstanceNoTex));
|
||||
CGraphics::DrawInstances(0, 4, g_instNoTexData.size());
|
||||
CGraphics::DrawInstances(boo::Primitive::TriStrips, 0, 4, g_instNoTexData.size());
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ private:
|
|||
bool x224_25_LIT_;
|
||||
bool x224_26_AAPH;
|
||||
bool x224_27_ZBUF;
|
||||
bool x224_28_zTest = true;
|
||||
bool x224_28_zTest = false;
|
||||
bool x224_29_MBLR;
|
||||
bool x224_30_VMD1;
|
||||
bool x224_31_VMD2;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
static IDataBindingFactory* Initialize(boo::GLDataFactory& factory);
|
||||
#if _WIN32
|
||||
static IDataBindingFactory* Initialize(boo::ID3DDataFactory& factory);
|
||||
#elif __APPLE__
|
||||
#elif BOO_HAS_METAL
|
||||
static IDataBindingFactory* Initialize(boo::MetalDataFactory& factory);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace pshag
|
|||
|
||||
static const char* VS_GLSL_TEX =
|
||||
"#version 330\n"
|
||||
"layout(location=0) in vec3 posIn[4];\n"
|
||||
"layout(location=0) in vec4 posIn[4];\n"
|
||||
"layout(location=4) in vec4 colorIn;\n"
|
||||
"layout(location=5) in vec2 uvsIn[4];\n"
|
||||
"\n"
|
||||
|
@ -29,6 +29,7 @@ static const char* VS_GLSL_TEX =
|
|||
" vtf.color = colorIn * moduColor;\n"
|
||||
" vtf.uv = uvsIn[gl_VertexID];\n"
|
||||
" gl_Position = mvp * posIn[gl_VertexID];\n"
|
||||
" gl_Position = vec4(posIn[gl_VertexID].x, posIn[gl_VertexID].z, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_TEX =
|
||||
|
@ -45,6 +46,7 @@ static const char* FS_GLSL_TEX =
|
|||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color * texture(texs[0], vtf.uv);\n"
|
||||
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_TEX_REDTOALPHA =
|
||||
|
@ -62,11 +64,12 @@ static const char* FS_GLSL_TEX_REDTOALPHA =
|
|||
"{\n"
|
||||
" colorOut = vtf.color * texture(texs[0], vtf.uv);\n"
|
||||
" colorOut.a = colorOut.r;\n"
|
||||
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VS_GLSL_INDTEX =
|
||||
"#version 330\n"
|
||||
"layout(location=0) in vec3 posIn[4];\n"
|
||||
"layout(location=0) in vec4 posIn[4];\n"
|
||||
"layout(location=4) in vec4 colorIn;\n"
|
||||
"layout(location=5) in vec4 uvsInTexrTind[4];\n"
|
||||
"layout(location=9) in vec2 uvsInScene[4];\n"
|
||||
|
@ -110,11 +113,12 @@ static const char* FS_GLSL_INDTEX =
|
|||
"uniform sampler2D texs[3];\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 tindTexel = texture(texs[2], vtf.uvTind);\n"
|
||||
" vec2 tindTexel = texture(texs[2], vtf.uvTind).xy;\n"
|
||||
" vec4 sceneTexel = texture(texs[1], vtf.uvScene + tindTexel);\n"
|
||||
" vec4 texrTexel = texture(texs[0], vtf.uvTexr);\n"
|
||||
" colorOut = vtf.color * sceneTexel + texrTexel;\n"
|
||||
" colorOut.a = vtf.color.a * texrTexel.a;"
|
||||
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS_GLSL_CINDTEX =
|
||||
|
@ -132,14 +136,15 @@ static const char* FS_GLSL_CINDTEX =
|
|||
"uniform sampler2D texs[3];\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 tindTexel = texture(texs[2], vtf.uvTind);\n"
|
||||
" vec2 tindTexel = texture(texs[2], vtf.uvTind).xy;\n"
|
||||
" vec4 sceneTexel = texture(texs[1], vtf.uvScene + tindTexel);\n"
|
||||
" colorOut = vtf.color * sceneTexel * texture(texs[0], vtf.uvTexr);\n"
|
||||
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* VS_GLSL_NOTEX =
|
||||
"#version 330\n"
|
||||
"layout(location=0) in vec3 posIn[4];\n"
|
||||
"layout(location=0) in vec4 posIn[4];\n"
|
||||
"layout(location=4) in vec4 colorIn;\n"
|
||||
"\n"
|
||||
"uniform ParticleUniform\n"
|
||||
|
@ -172,6 +177,7 @@ static const char* FS_GLSL_NOTEX =
|
|||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color;\n"
|
||||
" colorOut = vec4(1.0,1.0,1.0,1.0);\n"
|
||||
"}\n";
|
||||
|
||||
struct DataBindingFactory : CElementGenShaders::IDataBindingFactory
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#include "CEmitterElement.hpp"
|
||||
|
||||
namespace pshag
|
||||
{
|
||||
|
||||
bool CEESimpleEmitter::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
|
||||
{
|
||||
}
|
||||
|
||||
bool CVESphere::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
|
||||
{
|
||||
}
|
||||
|
||||
bool CVEAngleSphere::GetValue(int frame, Zeus::CVector3f& pPos, Zeus::CVector3f& pVel) const
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -105,6 +105,19 @@ bool CREClamp::GetValue(int frame,float& valOut) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CREInitialRandom::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
if (frame == 0)
|
||||
{
|
||||
float a, b;
|
||||
x4_min->GetValue(frame, a);
|
||||
x8_max->GetValue(frame, b);
|
||||
float rand = CRandom16::GetRandomNumber()->Float();
|
||||
valOut = b * rand + a * (1.0f - rand);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CRERandom::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
float a, b;
|
||||
|
@ -217,61 +230,61 @@ bool CRECompareEquals::GetValue(int frame, float& valOut) const
|
|||
|
||||
bool CREParticleAccessParam1::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[0];
|
||||
//valOut = CParticleGlobals::g_papValues[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam2::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[1];
|
||||
//valOut = CParticleGlobals::g_papValues[1];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam3::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[2];
|
||||
//valOut = CParticleGlobals::g_papValues[2];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam4::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[3];
|
||||
//valOut = CParticleGlobals::g_papValues[3];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam5::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[4];
|
||||
//valOut = CParticleGlobals::g_papValues[4];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam6::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[5];
|
||||
//valOut = CParticleGlobals::g_papValues[5];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam7::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[6];
|
||||
//valOut = CParticleGlobals::g_papValues[6];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREParticleAccessParam8::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_papValues[7];
|
||||
//valOut = CParticleGlobals::g_papValues[7];
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREPSLL::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_particleMetrics->x2c_psll;
|
||||
//valOut = CParticleGlobals::g_particleMetrics->x2c_psll;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CREPRLW::GetValue(int frame, float& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_particleMetrics->x30_prlw;
|
||||
//valOut = CParticleGlobals::g_particleMetrics->x30_prlw;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -268,6 +268,12 @@ bool CVEParticleVelocity::GetValue(int /*frame*/, Zeus::CVector3f& valOut) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CVESPOS::GetValue(int frame, Zeus::CVector3f& valOut) const
|
||||
{
|
||||
/* TODO: Do */
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVEPLCO::GetValue(int /*frame*/, Zeus::CVector3f& valOut) const
|
||||
{
|
||||
valOut = CParticleGlobals::g_particleMetrics->x10_plco;
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 2c5df80a56a07f9147e82a5981dcd311304f3b1d
|
||||
Subproject commit 268a2071b75323022ef4f4cf61f9f8441b6579d2
|
|
@ -1 +1 @@
|
|||
Subproject commit ca6d7ff93bb8cf951d47752c0892258330bf5caa
|
||||
Subproject commit 0d22ed8d625a58d8eac7a63d09c80c490d581db2
|
Loading…
Reference in New Issue