mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-09 22:27:41 +00:00
Humungous refactor
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#ifndef __PSHAG_CBOORENDERER_HPP__
|
||||
#define __PSHAG_CBOORENDERER_HPP__
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
class IObjectStore;
|
||||
class CMemorySys;
|
||||
|
||||
230
Runtime/Graphics/CGraphics.cpp
Normal file
230
Runtime/Graphics/CGraphics.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "zeus/Math.hpp"
|
||||
|
||||
#undef near
|
||||
#undef far
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CGraphics::CProjectionState CGraphics::g_Proj;
|
||||
float CGraphics::g_ProjAspect = 1.f;
|
||||
u32 CGraphics::g_NumLightsActive = 0;
|
||||
ERglLight CGraphics::g_LightActive = ERglLight::None;
|
||||
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
|
||||
zeus::CTransform CGraphics::g_GXModelView;
|
||||
zeus::CTransform CGraphics::g_GXModelMatrix;
|
||||
zeus::CTransform CGraphics::g_ViewMatrix;
|
||||
zeus::CVector3f CGraphics::g_ViewPoint;
|
||||
zeus::CTransform CGraphics::g_GXViewPointMatrix;
|
||||
zeus::CTransform CGraphics::g_CameraMatrix;
|
||||
zeus::CVector2i CGraphics::g_ViewportResolution;
|
||||
zeus::CVector2i CGraphics::g_ViewportResolutionHalf;
|
||||
int CGraphics::g_ViewportSamples = 1;
|
||||
bool CGraphics::g_IsGXModelMatrixIdentity;
|
||||
|
||||
void CGraphics::DisableAllLights()
|
||||
{
|
||||
g_NumLightsActive = 0;
|
||||
g_LightActive = ERglLight::None;
|
||||
// TODO: turn lights off for real
|
||||
}
|
||||
|
||||
void CGraphics::EnableLight(ERglLight light)
|
||||
{
|
||||
if ((light & g_LightActive) == ERglLight::None)
|
||||
{
|
||||
g_LightActive |= light;
|
||||
++g_NumLightsActive;
|
||||
// TODO: turn light on for real
|
||||
}
|
||||
g_LightsWereOn = g_LightActive;
|
||||
}
|
||||
|
||||
void CGraphics::SetLightState(ERglLight lightState)
|
||||
{
|
||||
// TODO: set state for real
|
||||
g_LightActive = lightState;
|
||||
g_NumLightsActive = zeus::PopCount(lightState);
|
||||
}
|
||||
|
||||
void CGraphics::SetDepthWriteMode(bool test, ERglEnum comp, bool write)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGraphics::SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp)
|
||||
{
|
||||
}
|
||||
|
||||
void CGraphics::SetCullMode(ERglCullMode)
|
||||
{
|
||||
}
|
||||
|
||||
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1)
|
||||
{
|
||||
}
|
||||
|
||||
void CGraphics::SetViewPointMatrix(const zeus::CTransform& xf)
|
||||
{
|
||||
g_ViewMatrix = xf;
|
||||
g_ViewPoint = xf.m_origin;
|
||||
zeus::CMatrix3f tmp(xf.m_basis[0], xf.m_basis[2], -xf.m_basis[1]);
|
||||
g_GXViewPointMatrix = zeus::CTransform(tmp.transposed());
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
void CGraphics::SetViewMatrix()
|
||||
{
|
||||
g_CameraMatrix = g_GXViewPointMatrix * zeus::CTransform::Translate(-g_ViewPoint);
|
||||
if (g_IsGXModelMatrixIdentity)
|
||||
g_GXModelView = g_CameraMatrix;
|
||||
else
|
||||
g_GXModelView = g_CameraMatrix * g_GXModelMatrix;
|
||||
/* Load position matrix */
|
||||
/* Inverse-transpose */
|
||||
/* Load normal matrix */
|
||||
}
|
||||
|
||||
void CGraphics::SetModelMatrix(const zeus::CTransform& xf)
|
||||
{
|
||||
g_IsGXModelMatrixIdentity = false;
|
||||
g_GXModelMatrix = xf;
|
||||
SetViewMatrix();
|
||||
}
|
||||
|
||||
zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix()
|
||||
{
|
||||
float rml = g_Proj.x8_right - g_Proj.x4_left;
|
||||
float rpl = g_Proj.x8_right + g_Proj.x4_left;
|
||||
float tmb = g_Proj.xc_top - g_Proj.x10_bottom;
|
||||
float tpb = g_Proj.xc_top + g_Proj.x10_bottom;
|
||||
float fmn = g_Proj.x18_far - g_Proj.x14_near;
|
||||
float fpn = g_Proj.x18_far + g_Proj.x14_near;
|
||||
return zeus::CMatrix4f(2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f,
|
||||
0.f, 2.f * g_Proj.x14_near / tmb, tpb / tmb, 0.f,
|
||||
0.f, 0.f, -fpn / fmn, -2.f * g_Proj.x18_far * g_Proj.x14_near / fmn,
|
||||
0.f, 0.f, -1.f, 0.f);
|
||||
}
|
||||
|
||||
const CGraphics::CProjectionState& CGraphics::GetProjectionState()
|
||||
{
|
||||
return g_Proj;
|
||||
}
|
||||
|
||||
void CGraphics::SetProjectionState(const CGraphics::CProjectionState& proj)
|
||||
{
|
||||
g_Proj = proj;
|
||||
FlushProjection();
|
||||
}
|
||||
|
||||
void CGraphics::SetPerspective(float fovy, float aspect, float near, float far)
|
||||
{
|
||||
g_ProjAspect = aspect;
|
||||
|
||||
float tfov = std::tan(zeus::degToRad(fovy * 0.5f));
|
||||
g_Proj.x0_persp = true;
|
||||
g_Proj.x14_near = near;
|
||||
g_Proj.x18_far = far;
|
||||
g_Proj.xc_top = near * tfov;
|
||||
g_Proj.x10_bottom = -g_Proj.xc_top;
|
||||
g_Proj.x8_right = aspect * near * tfov;
|
||||
g_Proj.x4_left = -g_Proj.x8_right;
|
||||
}
|
||||
|
||||
void CGraphics::FlushProjection()
|
||||
{
|
||||
if (g_Proj.x0_persp)
|
||||
{
|
||||
// Convert and load persp
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert and load ortho
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CVector2i CGraphics::ProjectPoint(const zeus::CVector3f& point)
|
||||
{
|
||||
zeus::CVector3f projPt = GetPerspectiveProjectionMatrix().multiplyOneOverW(point);
|
||||
return {int(projPt.x * g_ViewportResolutionHalf.x) + g_ViewportResolutionHalf.x,
|
||||
g_ViewportResolution.y - (int(projPt.y * g_ViewportResolutionHalf.y) + g_ViewportResolutionHalf.y)};
|
||||
}
|
||||
|
||||
SClipScreenRect CGraphics::ClipScreenRectFromMS(const zeus::CVector3f& p1,
|
||||
const zeus::CVector3f& p2)
|
||||
{
|
||||
zeus::CVector3f xf1 = g_GXModelView * p1;
|
||||
zeus::CVector3f xf2 = g_GXModelView * p2;
|
||||
return ClipScreenRectFromVS(xf1, xf2);
|
||||
}
|
||||
|
||||
SClipScreenRect CGraphics::ClipScreenRectFromVS(const zeus::CVector3f& p1,
|
||||
const zeus::CVector3f& p2)
|
||||
{
|
||||
if (p1.x == 0.f && p1.y == 0.f && p1.z == 0.f)
|
||||
return {};
|
||||
if (p2.x == 0.f && p2.y == 0.f && p2.z == 0.f)
|
||||
return {};
|
||||
|
||||
if (p1.y < GetProjectionState().x14_near || p2.y < GetProjectionState().x14_near)
|
||||
return {};
|
||||
if (p1.y > GetProjectionState().x18_far || p2.y > GetProjectionState().x18_far)
|
||||
return {};
|
||||
|
||||
zeus::CVector2i sp1 = ProjectPoint(p1);
|
||||
zeus::CVector2i sp2 = ProjectPoint(p2);
|
||||
int minX = std::min(sp2.x, sp1.x);
|
||||
int minX2 = minX & 0xfffffffe;
|
||||
int minY = std::min(sp2.y, sp1.y);
|
||||
int minY2 = minY & 0xfffffffe;
|
||||
|
||||
|
||||
if (minX2 >= g_ViewportResolution.x)
|
||||
return {};
|
||||
|
||||
int maxX = abs(sp1.x - sp2.x) + minX;
|
||||
int maxX2 = (maxX + 2) & 0xfffffffe;
|
||||
if (maxX2 <= 0 /* ViewportX origin */)
|
||||
return {};
|
||||
|
||||
int finalMinX = std::max(minX, 0 /* ViewportX origin */);
|
||||
int finalMaxX = std::min(maxX, g_ViewportResolution.x);
|
||||
|
||||
|
||||
if (minY2 >= g_ViewportResolution.y)
|
||||
return {};
|
||||
|
||||
int maxY = abs(sp1.y - sp2.y) + minY;
|
||||
int maxY2 = (maxY + 2) & 0xfffffffe;
|
||||
if (maxY2 <= 0 /* ViewportY origin */)
|
||||
return {};
|
||||
|
||||
int finalMinY = std::max(minY, 0 /* ViewportY origin */);
|
||||
int finalMaxY = std::min(maxY, g_ViewportResolution.y);
|
||||
|
||||
int width = maxX2 - minX2;
|
||||
int height = maxY2 - minY2;
|
||||
return {true, minX2, minY2, width, height, width,
|
||||
minX2 / float(g_ViewportResolution.x), maxX2 / float(g_ViewportResolution.x),
|
||||
1.f - maxY2 / float(g_ViewportResolution.y), 1.f - minY2 / float(g_ViewportResolution.y)};
|
||||
|
||||
}
|
||||
|
||||
zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3f& point)
|
||||
{
|
||||
zeus::CVector3f pt = g_GXModelView * point;
|
||||
return GetPerspectiveProjectionMatrix().multiplyOneOverW(pt);
|
||||
}
|
||||
|
||||
void CGraphics::SetViewportResolution(const zeus::CVector2i& res)
|
||||
{
|
||||
g_ViewportResolution = res;
|
||||
g_ViewportResolutionHalf = {res.x / 2, res.y / 2};
|
||||
}
|
||||
|
||||
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
|
||||
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
|
||||
boo::ITextureR* CGraphics::g_SpareTexture = nullptr;
|
||||
|
||||
}
|
||||
229
Runtime/Graphics/CGraphics.hpp
Normal file
229
Runtime/Graphics/CGraphics.hpp
Normal file
@@ -0,0 +1,229 @@
|
||||
#ifndef __PSHAG_CGRAPHICS_HPP__
|
||||
#define __PSHAG_CGRAPHICS_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
#include "zeus/CVector2i.hpp"
|
||||
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsCommandQueue.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
enum class ERglLight : u8
|
||||
{
|
||||
None = 0,
|
||||
Zero = 1,
|
||||
One = 1 << 1,
|
||||
Two = 1 << 2,
|
||||
Three = 1 << 3,
|
||||
Four = 1 << 4,
|
||||
Five = 1 << 5,
|
||||
Six = 1 << 6,
|
||||
Seven = 1 << 7
|
||||
};
|
||||
ENABLE_BITWISE_ENUM(ERglLight)
|
||||
|
||||
enum class ERglEnum
|
||||
{
|
||||
Never = 0,
|
||||
Less = 1,
|
||||
Equal = 2,
|
||||
LEqual = 3,
|
||||
Greater = 4,
|
||||
NEqual = 5,
|
||||
GEqual = 6,
|
||||
Always = 7
|
||||
};
|
||||
|
||||
enum class ERglBlendMode
|
||||
{
|
||||
None = 0,
|
||||
Blend = 1,
|
||||
Logic = 2,
|
||||
Subtract = 3
|
||||
};
|
||||
|
||||
enum class ERglBlendFactor
|
||||
{
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
SrcColor = 2,
|
||||
InvSrcColor = 3,
|
||||
SrcAlpha = 4,
|
||||
InvSrcAlpha = 5,
|
||||
DstAlpha = 6,
|
||||
InvDstAlpha = 7
|
||||
};
|
||||
|
||||
enum class ERglLogicOp
|
||||
{
|
||||
Clear = 0,
|
||||
And = 1,
|
||||
RevAnd = 2,
|
||||
Copy = 3,
|
||||
InvAnd = 4,
|
||||
NoOp = 5,
|
||||
Xor = 6,
|
||||
Or = 7,
|
||||
Nor = 8,
|
||||
Equiv = 9,
|
||||
Inv = 10,
|
||||
RevOr = 11,
|
||||
InvCopy = 12,
|
||||
InvOr = 13,
|
||||
NAnd = 14,
|
||||
Set = 15
|
||||
};
|
||||
|
||||
enum class ERglCullMode
|
||||
{
|
||||
None = 0,
|
||||
Front = 1,
|
||||
Back = 2,
|
||||
All = 3
|
||||
};
|
||||
|
||||
enum class ERglAlphaFunc
|
||||
{
|
||||
Never = 0,
|
||||
Less = 1,
|
||||
Equal = 2,
|
||||
LEqual = 3,
|
||||
Greater = 4,
|
||||
NEqual = 5,
|
||||
GEqual = 6,
|
||||
Always = 7
|
||||
};
|
||||
|
||||
enum class ERglAlphaOp
|
||||
{
|
||||
And = 0,
|
||||
Or = 1,
|
||||
Xor = 2,
|
||||
XNor = 3
|
||||
};
|
||||
|
||||
struct SClipScreenRect
|
||||
{
|
||||
bool x0_valid;
|
||||
int x4_left;
|
||||
int x8_top;
|
||||
int xc_width;
|
||||
int x10_height;
|
||||
int x14_dstWidth;
|
||||
float x18_uvXMin;
|
||||
float x1c_uvXMax;
|
||||
float x20_uvYMin;
|
||||
float x24_uvYMax;
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
struct CProjectionState
|
||||
{
|
||||
bool x0_persp;
|
||||
float x4_left;
|
||||
float x8_right;
|
||||
float xc_top;
|
||||
float x10_bottom;
|
||||
float x14_near;
|
||||
float x18_far;
|
||||
};
|
||||
static CProjectionState g_Proj;
|
||||
static float g_ProjAspect;
|
||||
static u32 g_NumLightsActive;
|
||||
static ERglLight g_LightActive;
|
||||
static ERglLight g_LightsWereOn;
|
||||
static zeus::CTransform g_GXModelView;
|
||||
static zeus::CTransform g_GXModelMatrix;
|
||||
static zeus::CTransform g_ViewMatrix;
|
||||
static zeus::CVector3f g_ViewPoint;
|
||||
static zeus::CTransform g_GXViewPointMatrix;
|
||||
static zeus::CTransform g_CameraMatrix;
|
||||
static zeus::CVector2i g_ViewportResolution;
|
||||
static zeus::CVector2i g_ViewportResolutionHalf;
|
||||
static int g_ViewportSamples;
|
||||
static bool g_IsGXModelMatrixIdentity;
|
||||
|
||||
static void DisableAllLights();
|
||||
static void EnableLight(ERglLight light);
|
||||
static void SetLightState(ERglLight lightState);
|
||||
static void SetDepthWriteMode(bool test, ERglEnum comp, bool write);
|
||||
static void SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp);
|
||||
static void SetCullMode(ERglCullMode);
|
||||
static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1);
|
||||
static void SetViewPointMatrix(const zeus::CTransform& xf);
|
||||
static void SetViewMatrix();
|
||||
static void SetModelMatrix(const zeus::CTransform& xf);
|
||||
static zeus::CMatrix4f GetPerspectiveProjectionMatrix();
|
||||
static const CProjectionState& GetProjectionState();
|
||||
static void SetProjectionState(const CProjectionState&);
|
||||
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);
|
||||
static SClipScreenRect ClipScreenRectFromVS(const zeus::CVector3f& p1, const zeus::CVector3f& p2);
|
||||
static zeus::CVector3f ProjectModelPointToViewportSpace(const zeus::CVector3f& point);
|
||||
static void SetViewportResolution(const zeus::CVector2i& res);
|
||||
|
||||
static boo::IGraphicsDataFactory* g_BooFactory;
|
||||
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
|
||||
static boo::ITextureR* g_SpareTexture;
|
||||
|
||||
static void InitializeBoo(boo::IGraphicsDataFactory* factory,
|
||||
boo::IGraphicsCommandQueue* cc,
|
||||
boo::ITextureR* spareTex)
|
||||
{
|
||||
g_BooFactory = factory;
|
||||
g_BooMainCommandQueue = cc;
|
||||
g_SpareTexture = spareTex;
|
||||
}
|
||||
|
||||
static boo::IGraphicsBufferD* NewDynamicGPUBuffer(boo::BufferUse use, size_t stride, size_t count)
|
||||
{
|
||||
return g_BooFactory->newDynamicBuffer(use, stride, count);
|
||||
}
|
||||
static boo::GraphicsDataToken CommitResources()
|
||||
{
|
||||
return g_BooFactory->commit();
|
||||
}
|
||||
static void SetShaderDataBinding(boo::IShaderDataBinding* binding)
|
||||
{
|
||||
g_BooMainCommandQueue->setShaderDataBinding(binding);
|
||||
}
|
||||
static void ResolveSpareTexture(const SClipScreenRect& rect)
|
||||
{
|
||||
boo::SWindowRect wrect = {rect.x4_left, rect.x8_top, rect.xc_width, rect.x10_height};
|
||||
g_BooMainCommandQueue->resolveBindTexture(g_SpareTexture, wrect, true, true, false);
|
||||
}
|
||||
static void DrawInstances(size_t start, size_t count, size_t instCount)
|
||||
{
|
||||
g_BooMainCommandQueue->drawInstances(start, count, instCount);
|
||||
}
|
||||
static void DrawArray(size_t start, size_t count)
|
||||
{
|
||||
g_BooMainCommandQueue->draw(start, count);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __PSHAG_CGRAPHICS_HPP__
|
||||
24
Runtime/Graphics/CLight.cpp
Normal file
24
Runtime/Graphics/CLight.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "CLight.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
CLight CLight::BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color, float angle)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
CLight CLight::BuildCustom(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color, float constAtt, float linearAtt, float quadAtt,
|
||||
float intensity, float, float)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +1,39 @@
|
||||
#ifndef __PSHAG_CLIGHT_HPP__
|
||||
#define __PSHAG_CLIGHT_HPP__
|
||||
|
||||
class CLight
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
enum class ELightType
|
||||
{
|
||||
LocalAmbient,
|
||||
Directional,
|
||||
Custom,
|
||||
Spot,
|
||||
Spot2,
|
||||
LocalAmbient2
|
||||
};
|
||||
enum class EFalloffType
|
||||
{
|
||||
Constant,
|
||||
Linear,
|
||||
Quadratic
|
||||
};
|
||||
|
||||
class CLight
|
||||
{
|
||||
public:
|
||||
static CLight BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color);
|
||||
static CLight BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color, float angle);
|
||||
static CLight BuildCustom(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
|
||||
const zeus::CColor& color, float constAtt, float linearAtt, float quadAtt,
|
||||
float intensity, float, float);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __PSHAG_CLIGHT_HPP__
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "CLineRenderer.hpp"
|
||||
#include "CLineRendererShaders.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
LogVisor::LogModule LineRendererLog("pshag::CLineRenderer");
|
||||
logvisor::Module LineRendererLog("urde::CLineRenderer");
|
||||
|
||||
boo::IShaderPipeline* CLineRendererShaders::m_texAlpha = nullptr;
|
||||
boo::IShaderPipeline* CLineRendererShaders::m_texAdditive = nullptr;
|
||||
@@ -66,20 +66,20 @@ void CLineRenderer::Shutdown()
|
||||
|
||||
struct SDrawVertTex
|
||||
{
|
||||
Zeus::CVector4f pos;
|
||||
Zeus::CColor color;
|
||||
Zeus::CVector2f uv;
|
||||
zeus::CVector4f pos;
|
||||
zeus::CColor color;
|
||||
zeus::CVector2f uv;
|
||||
};
|
||||
|
||||
struct SDrawVertNoTex
|
||||
{
|
||||
Zeus::CVector4f pos;
|
||||
Zeus::CColor color;
|
||||
zeus::CVector4f pos;
|
||||
zeus::CColor color;
|
||||
};
|
||||
|
||||
struct SDrawUniform
|
||||
{
|
||||
Zeus::CColor moduColor;
|
||||
zeus::CColor moduColor;
|
||||
};
|
||||
|
||||
void CLineRendererShaders::BuildShaderDataBinding(CLineRenderer& renderer,
|
||||
@@ -109,7 +109,7 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* t
|
||||
{
|
||||
if (maxVerts < 2)
|
||||
{
|
||||
LineRendererLog.report(LogVisor::FatalError, _S("maxVerts < 2, maxVerts = %i"), maxVerts);
|
||||
LineRendererLog.report(logvisor::Fatal, _S("maxVerts < 2, maxVerts = %i"), maxVerts);
|
||||
return;
|
||||
}
|
||||
m_textured = texture != nullptr;
|
||||
@@ -139,11 +139,11 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* t
|
||||
static rstl::reserved_vector<SDrawVertTex, 256> g_StaticLineVertsTex;
|
||||
static rstl::reserved_vector<SDrawVertNoTex, 256> g_StaticLineVertsNoTex;
|
||||
|
||||
static Zeus::CVector2f IntersectLines(const Zeus::CVector2f& pa1, const Zeus::CVector2f& pa2,
|
||||
const Zeus::CVector2f& pb1, const Zeus::CVector2f& pb2)
|
||||
static zeus::CVector2f IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa2,
|
||||
const zeus::CVector2f& pb1, const zeus::CVector2f& pb2)
|
||||
{
|
||||
Zeus::CVector2f pa1mpa2 = pa1 - pa2;
|
||||
Zeus::CVector2f pb1mpb2 = pb1 - pb2;
|
||||
zeus::CVector2f pa1mpa2 = pa1 - pa2;
|
||||
zeus::CVector2f pb1mpb2 = pb1 - pb2;
|
||||
float denom = pa1mpa2.x * pb1mpb2.y - pa1mpa2.y * pb1mpb2.x;
|
||||
float numt1 = pa1.x * pa2.y - pa1.y * pa2.x;
|
||||
float numt2 = pb1.x * pb2.y - pb1.y * pb2.x;
|
||||
@@ -161,14 +161,14 @@ void CLineRenderer::Reset()
|
||||
g_StaticLineVertsNoTex.clear();
|
||||
}
|
||||
|
||||
void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColor& color, float width,
|
||||
const Zeus::CVector2f& uv)
|
||||
void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColor& color, float width,
|
||||
const zeus::CVector2f& uv)
|
||||
{
|
||||
if (m_final || !m_shaderBind || m_nextVert >= m_maxVerts)
|
||||
return;
|
||||
|
||||
float adjWidth = width / 480.f;
|
||||
Zeus::CVector3f projPt = CGraphics::ProjectModelPointToViewportSpace(position);
|
||||
zeus::CVector3f projPt = CGraphics::ProjectModelPointToViewportSpace(position);
|
||||
|
||||
if (m_mode == EPrimitiveMode::LineLoop)
|
||||
{
|
||||
@@ -188,13 +188,13 @@ void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColo
|
||||
|
||||
if (m_nextVert > 1)
|
||||
{
|
||||
Zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
|
||||
zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
|
||||
if (!dva.canBeNormalized())
|
||||
dva = {0.f, 1.f};
|
||||
dva = dva.normalized().perpendicularVector() * m_lastWidth;
|
||||
dva.x /= CGraphics::g_ProjAspect;
|
||||
|
||||
Zeus::CVector2f dvb = (projPt - m_lastPos).toVec2f();
|
||||
zeus::CVector2f dvb = (projPt - m_lastPos).toVec2f();
|
||||
if (!dvb.canBeNormalized())
|
||||
dvb = {0.f, 1.f};
|
||||
dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
|
||||
@@ -219,11 +219,11 @@ void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColo
|
||||
}
|
||||
else
|
||||
{
|
||||
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb);
|
||||
intersect1.z = m_lastPos.z;
|
||||
|
||||
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb);
|
||||
intersect2.z = m_lastPos.z;
|
||||
|
||||
@@ -250,11 +250,11 @@ void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColo
|
||||
}
|
||||
else
|
||||
{
|
||||
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb);
|
||||
intersect1.z = m_lastPos.z;
|
||||
|
||||
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb);
|
||||
intersect2.z = m_lastPos.z;
|
||||
|
||||
@@ -265,7 +265,7 @@ void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColo
|
||||
}
|
||||
else if (m_nextVert == 1)
|
||||
{
|
||||
Zeus::CVector2f dv = (projPt - m_lastPos).toVec2f();
|
||||
zeus::CVector2f dv = (projPt - m_lastPos).toVec2f();
|
||||
if (!dv.canBeNormalized())
|
||||
dv = {0.f, 1.f};
|
||||
dv = dv.normalized().perpendicularVector() * m_lastWidth;
|
||||
@@ -290,30 +290,30 @@ void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColo
|
||||
++m_nextVert;
|
||||
}
|
||||
|
||||
void CLineRenderer::Render(const Zeus::CColor& moduColor)
|
||||
void CLineRenderer::Render(const zeus::CColor& moduColor)
|
||||
{
|
||||
if (!m_final && m_nextVert > 1)
|
||||
{
|
||||
if (m_mode == EPrimitiveMode::LineLoop)
|
||||
{
|
||||
{
|
||||
Zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
|
||||
zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
|
||||
if (!dva.canBeNormalized())
|
||||
dva = {0.f, 1.f};
|
||||
dva = dva.normalized().perpendicularVector() * m_lastWidth;
|
||||
dva.x /= CGraphics::g_ProjAspect;
|
||||
|
||||
Zeus::CVector2f dvb = (m_firstPos - m_lastPos).toVec2f();
|
||||
zeus::CVector2f dvb = (m_firstPos - m_lastPos).toVec2f();
|
||||
if (!dvb.canBeNormalized())
|
||||
dvb = {0.f, 1.f};
|
||||
dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
|
||||
dvb.x /= CGraphics::g_ProjAspect;
|
||||
|
||||
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||
m_lastPos.toVec2f() + dvb, m_firstPos.toVec2f() + dvb);
|
||||
intersect1.z = m_lastPos.z;
|
||||
|
||||
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||
m_lastPos.toVec2f() - dvb, m_firstPos.toVec2f() - dvb);
|
||||
intersect2.z = m_lastPos.z;
|
||||
|
||||
@@ -329,23 +329,23 @@ void CLineRenderer::Render(const Zeus::CColor& moduColor)
|
||||
}
|
||||
}
|
||||
{
|
||||
Zeus::CVector2f dva = (m_firstPos - m_lastPos).toVec2f();
|
||||
zeus::CVector2f dva = (m_firstPos - m_lastPos).toVec2f();
|
||||
if (!dva.canBeNormalized())
|
||||
dva = {0.f, 1.f};
|
||||
dva = dva.normalized().perpendicularVector() * m_firstWidth;
|
||||
dva.x /= CGraphics::g_ProjAspect;
|
||||
|
||||
Zeus::CVector2f dvb = (m_secondPos - m_firstPos).toVec2f();
|
||||
zeus::CVector2f dvb = (m_secondPos - m_firstPos).toVec2f();
|
||||
if (!dvb.canBeNormalized())
|
||||
dvb = {0.f, 1.f};
|
||||
dvb = dvb.normalized().perpendicularVector() * m_firstWidth;
|
||||
dvb.x /= CGraphics::g_ProjAspect;
|
||||
|
||||
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva,
|
||||
zeus::CVector3f intersect1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva,
|
||||
m_firstPos.toVec2f() + dvb, m_secondPos.toVec2f() + dvb);
|
||||
intersect1.z = m_firstPos.z;
|
||||
|
||||
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva,
|
||||
zeus::CVector3f intersect2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva,
|
||||
m_firstPos.toVec2f() - dvb, m_secondPos.toVec2f() - dvb);
|
||||
intersect2.z = m_firstPos.z;
|
||||
|
||||
@@ -363,7 +363,7 @@ void CLineRenderer::Render(const Zeus::CColor& moduColor)
|
||||
}
|
||||
else
|
||||
{
|
||||
Zeus::CVector2f dv = (m_lastPos - m_lastPos2).toVec2f();
|
||||
zeus::CVector2f dv = (m_lastPos - m_lastPos2).toVec2f();
|
||||
if (!dv.canBeNormalized())
|
||||
dv = {0.f, 1.f};
|
||||
dv = dv.normalized().perpendicularVector() * m_lastWidth;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
#define __PSHAG_CLINERENDERER_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "CVector3f.hpp"
|
||||
#include "CColor.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CLineRenderer
|
||||
@@ -26,16 +26,16 @@ private:
|
||||
bool m_final = false;
|
||||
bool m_textured;
|
||||
|
||||
Zeus::CVector3f m_firstPos;
|
||||
Zeus::CVector3f m_secondPos;
|
||||
Zeus::CVector2f m_firstUV;
|
||||
Zeus::CColor m_firstColor;
|
||||
zeus::CVector3f m_firstPos;
|
||||
zeus::CVector3f m_secondPos;
|
||||
zeus::CVector2f m_firstUV;
|
||||
zeus::CColor m_firstColor;
|
||||
float m_firstWidth;
|
||||
|
||||
Zeus::CVector3f m_lastPos;
|
||||
Zeus::CVector3f m_lastPos2;
|
||||
Zeus::CVector2f m_lastUV;
|
||||
Zeus::CColor m_lastColor;
|
||||
zeus::CVector3f m_lastPos;
|
||||
zeus::CVector3f m_lastPos2;
|
||||
zeus::CVector2f m_lastUV;
|
||||
zeus::CColor m_lastColor;
|
||||
float m_lastWidth;
|
||||
|
||||
public:
|
||||
@@ -47,9 +47,9 @@ public:
|
||||
CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive);
|
||||
|
||||
void Reset();
|
||||
void AddVertex(const Zeus::CVector3f& position, const Zeus::CColor& color, float width,
|
||||
const Zeus::CVector2f& uv=Zeus::CVector2f::skZero);
|
||||
void Render(const Zeus::CColor& moduColor=Zeus::CColor::skWhite);
|
||||
void AddVertex(const zeus::CVector3f& position, const zeus::CColor& color, float width,
|
||||
const zeus::CVector2f& uv=zeus::CVector2f::skZero);
|
||||
void Render(const zeus::CColor& moduColor=zeus::CColor::skWhite);
|
||||
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#ifndef __PSHAG_CLINERENDERERSHADERS_HPP__
|
||||
#define __PSHAG_CLINERENDERERSHADERS_HPP__
|
||||
|
||||
#include "CGraphics.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "boo/graphicsdev/GL.hpp"
|
||||
#include "boo/graphicsdev/D3D.hpp"
|
||||
#include "boo/graphicsdev/Metal.hpp"
|
||||
#include "boo/graphicsdev/Vulkan.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
class CLineRenderer;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "CLineRendererShaders.hpp"
|
||||
#include "CLineRenderer.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_GLSL_TEX =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "CLineRendererShaders.hpp"
|
||||
#include "CLineRenderer.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_HLSL_TEX =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "CLineRendererShaders.hpp"
|
||||
#include "CLineRenderer.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS_METAL_TEX =
|
||||
|
||||
@@ -10,5 +10,8 @@ add_library(RuntimeCommonGraphics
|
||||
CLineRenderer.hpp CLineRenderer.cpp
|
||||
CLineRendererShaders.hpp CLineRendererShadersGLSL.cpp
|
||||
CMetroidModelInstance.hpp
|
||||
CLight.hpp
|
||||
CLight.hpp CLight.cpp
|
||||
CTexture.hpp CTextureBoo.cpp
|
||||
CModel.hpp CModelBoo.cpp
|
||||
CGraphics.hpp CGraphics.cpp
|
||||
${PLAT_SRCS})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PSHAG_CMETROIDMODELINSTANCE_HPP__
|
||||
#define __PSHAG_CMETROIDMODELINSTANCE_HPP__
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CMetroidModelInstance
|
||||
|
||||
26
Runtime/Graphics/CModel.hpp
Normal file
26
Runtime/Graphics/CModel.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __PSHAG_CMODEL_HPP__
|
||||
#define __PSHAG_CMODEL_HPP__
|
||||
|
||||
#include "RetroTypes.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
struct CModelFlags
|
||||
{
|
||||
u8 f1;
|
||||
u8 f2;
|
||||
u16 f3;
|
||||
zeus::CColor color;
|
||||
};
|
||||
|
||||
class CModel
|
||||
{
|
||||
public:
|
||||
void Draw(const CModelFlags& flags) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __PSHAG_CMODEL_HPP__
|
||||
10
Runtime/Graphics/CModelBoo.cpp
Normal file
10
Runtime/Graphics/CModelBoo.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "Graphics/CModel.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CModel::Draw(const CModelFlags& flags) const
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
55
Runtime/Graphics/CTexture.hpp
Normal file
55
Runtime/Graphics/CTexture.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef __PSHAG_CTEXTURE_HPP__
|
||||
#define __PSHAG_CTEXTURE_HPP__
|
||||
|
||||
#include "GCNTypes.hpp"
|
||||
#include "IObj.hpp"
|
||||
#include "IOStreams.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
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__
|
||||
695
Runtime/Graphics/CTextureBoo.cpp
Normal file
695
Runtime/Graphics/CTextureBoo.cpp
Normal file
@@ -0,0 +1,695 @@
|
||||
#include "CTexture.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "CToken.hpp"
|
||||
#include "Graphics/CGraphics.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::RGBA8,
|
||||
buf.get(), texelCount * 4, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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);
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
{
|
||||
u8 ind[4];
|
||||
u8 packed = source[x].lines[i];
|
||||
ind[3] = packed & 0x3;
|
||||
ind[2] = (packed >> 2) & 0x3;
|
||||
ind[1] = (packed >> 4) & 0x3;
|
||||
ind[0] = (packed >> 6) & 0x3;
|
||||
target[x].lines[i] = ind[0] | (ind[1] << 2) | (ind[2] << 4) | (ind[3] << 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
targetMip += w * h;
|
||||
|
||||
if (w > 1)
|
||||
w /= 2;
|
||||
if (h > 1)
|
||||
h /= 2;
|
||||
}
|
||||
|
||||
boo::ITextureS* tmp;
|
||||
m_booToken = CGraphics::g_BooFactory->newStaticTextureNoContext(x4_w, x6_h, x8_mips,
|
||||
boo::TextureFormat::DXT1,
|
||||
buf.get(), blockCount * 8, tmp);
|
||||
m_booTex = tmp;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
#include <vector>
|
||||
#include "../RetroTypes.hpp"
|
||||
#include "../CToken.hpp"
|
||||
#include "CAABox.hpp"
|
||||
#include "CPlane.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "zeus/CPlane.hpp"
|
||||
#include "CFrustum.hpp"
|
||||
#include "CColor.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
|
||||
namespace pshag
|
||||
namespace urde
|
||||
{
|
||||
class CMetroidModelInstance;
|
||||
class CLight;
|
||||
|
||||
Reference in New Issue
Block a user