mirror of https://github.com/AxioDL/metaforce.git
CBooRenderer: Make use of std::array where applicable
Makes the data strongly typed and allows eliminating some hardcoded sizes.
This commit is contained in:
parent
4f7f5cf09a
commit
b1426867bf
|
@ -13,6 +13,7 @@
|
||||||
#include "Runtime/World/CActor.hpp"
|
#include "Runtime/World/CActor.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <boo/System.hpp>
|
#include <boo/System.hpp>
|
||||||
#include <logvisor/logvisor.hpp>
|
#include <logvisor/logvisor.hpp>
|
||||||
|
@ -27,13 +28,34 @@
|
||||||
#define SPHERE_RAMP_RES 32
|
#define SPHERE_RAMP_RES 32
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
namespace {
|
||||||
|
struct FogVolumeControl {
|
||||||
|
std::array<std::array<u32, 2>, 12> xfc_{
|
||||||
|
{{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6}, {6, 4}, {0, 4}, {1, 5}, {3, 7}, {2, 6}},
|
||||||
|
};
|
||||||
|
std::array<u32, 8> x15c_{};
|
||||||
|
// GXVtxDescList x17c_; {{POS, DIRECT}, {TEX0, DIRECT}}
|
||||||
|
};
|
||||||
|
|
||||||
static logvisor::Module Log("CBooRenderer");
|
logvisor::Module Log("CBooRenderer");
|
||||||
|
|
||||||
static rstl::reserved_vector<CDrawable, 512> sDataHolder;
|
rstl::reserved_vector<CDrawable, 512> sDataHolder;
|
||||||
static rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50> sBucketsHolder;
|
rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50> sBucketsHolder;
|
||||||
static rstl::reserved_vector<CDrawablePlaneObject, 8> sPlaneObjectDataHolder;
|
rstl::reserved_vector<CDrawablePlaneObject, 8> sPlaneObjectDataHolder;
|
||||||
static rstl::reserved_vector<u16, 8> sPlaneObjectBucketHolder;
|
rstl::reserved_vector<u16, 8> sPlaneObjectBucketHolder;
|
||||||
|
|
||||||
|
constexpr FogVolumeControl s_FogVolumeCtrl{};
|
||||||
|
|
||||||
|
constexpr std::array<std::array<int, 2>, 3> OrthogonalAxis{
|
||||||
|
{{1, 2}, {0, 2}, {0, 1}},
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr bool TestBit(const u32* words, size_t bit) { return (words[bit / 32] & (1U << (bit & 0x1f))) != 0; }
|
||||||
|
|
||||||
|
float GetPlaneInterpolant(const zeus::CPlane& plane, const zeus::CVector3f& vert1, const zeus::CVector3f& vert2) {
|
||||||
|
return zeus::clamp(0.f, -plane.pointToPlaneDist(vert1) / (vert2 - vert1).dot(plane.normal()), 1.f);
|
||||||
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
class Buckets {
|
class Buckets {
|
||||||
friend class CBooRenderer;
|
friend class CBooRenderer;
|
||||||
|
@ -43,8 +65,8 @@ class Buckets {
|
||||||
static inline rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50>* sBuckets = nullptr;
|
static inline rstl::reserved_vector<rstl::reserved_vector<CDrawable*, 128>, 50>* sBuckets = nullptr;
|
||||||
static inline rstl::reserved_vector<CDrawablePlaneObject, 8>* sPlaneObjectData = nullptr;
|
static inline rstl::reserved_vector<CDrawablePlaneObject, 8>* sPlaneObjectData = nullptr;
|
||||||
static inline rstl::reserved_vector<u16, 8>* sPlaneObjectBucket = nullptr;
|
static inline rstl::reserved_vector<u16, 8>* sPlaneObjectBucket = nullptr;
|
||||||
static constexpr float skWorstMinMaxDistance[2] = {99999.0f, -99999.0f};
|
static constexpr std::array skWorstMinMaxDistance{99999.0f, -99999.0f};
|
||||||
static inline float sMinMaxDistance[2] = {0.0f, 0.0f};
|
static inline std::array sMinMaxDistance{0.0f, 0.0f};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Clear();
|
static void Clear();
|
||||||
|
@ -62,10 +84,10 @@ void Buckets::Clear() {
|
||||||
sBucketIndex.clear();
|
sBucketIndex.clear();
|
||||||
sPlaneObjectData->clear();
|
sPlaneObjectData->clear();
|
||||||
sPlaneObjectBucket->clear();
|
sPlaneObjectBucket->clear();
|
||||||
for (rstl::reserved_vector<CDrawable*, 128>& bucket : *sBuckets)
|
for (rstl::reserved_vector<CDrawable*, 128>& bucket : *sBuckets) {
|
||||||
bucket.clear();
|
bucket.clear();
|
||||||
sMinMaxDistance[0] = skWorstMinMaxDistance[0];
|
}
|
||||||
sMinMaxDistance[1] = skWorstMinMaxDistance[1];
|
sMinMaxDistance = skWorstMinMaxDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buckets::Sort() {
|
void Buckets::Sort() {
|
||||||
|
@ -167,12 +189,8 @@ void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDraw
|
||||||
|
|
||||||
const float dist = plane.pointToPlaneDist(pos);
|
const float dist = plane.pointToPlaneDist(pos);
|
||||||
sData->emplace_back(dtype, extraSort, dist, aabb, data);
|
sData->emplace_back(dtype, extraSort, dist, aabb, data);
|
||||||
if (sMinMaxDistance[0] > dist) {
|
sMinMaxDistance[0] = std::min(sMinMaxDistance[0], dist);
|
||||||
sMinMaxDistance[0] = dist;
|
sMinMaxDistance[1] = std::max(sMinMaxDistance[1], dist);
|
||||||
}
|
|
||||||
if (sMinMaxDistance[1] < dist) {
|
|
||||||
sMinMaxDistance[1] = dist;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buckets::Shutdown() {
|
void Buckets::Shutdown() {
|
||||||
|
@ -188,8 +206,7 @@ void Buckets::Init() {
|
||||||
sBuckets->resize(50);
|
sBuckets->resize(50);
|
||||||
sPlaneObjectData = &sPlaneObjectDataHolder;
|
sPlaneObjectData = &sPlaneObjectDataHolder;
|
||||||
sPlaneObjectBucket = &sPlaneObjectBucketHolder;
|
sPlaneObjectBucket = &sPlaneObjectBucketHolder;
|
||||||
sMinMaxDistance[0] = skWorstMinMaxDistance[0];
|
sMinMaxDistance = skWorstMinMaxDistance;
|
||||||
sMinMaxDistance[1] = skWorstMinMaxDistance[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
|
CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstance>* geom,
|
||||||
|
@ -205,50 +222,56 @@ CBooRenderer::CAreaListItem::CAreaListItem(const std::vector<CMetroidModelInstan
|
||||||
|
|
||||||
CBooRenderer::CAreaListItem::~CAreaListItem() {}
|
CBooRenderer::CAreaListItem::~CAreaListItem() {}
|
||||||
|
|
||||||
static inline bool TestBit(const u32* words, int bit) { return (words[bit / 32] & (1 << (bit & 0x1f))) != 0; }
|
|
||||||
|
|
||||||
void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) {
|
void CBooRenderer::ActivateLightsForModel(CAreaListItem* item, CBooModel& model) {
|
||||||
std::vector<CLight> thisLights;
|
std::vector<CLight> thisLights;
|
||||||
thisLights.reserve(4);
|
thisLights.reserve(4);
|
||||||
|
|
||||||
if (x300_dynamicLights.size()) {
|
if (x300_dynamicLights.size()) {
|
||||||
u32 lightOctreeWordCount = 0;
|
u32 lightOctreeWordCount = 0;
|
||||||
u32* lightOctreeWords = nullptr;
|
const u32* lightOctreeWords = nullptr;
|
||||||
if (item && model.x44_areaInstanceIdx != UINT32_MAX) {
|
if (item && model.x44_areaInstanceIdx != UINT32_MAX) {
|
||||||
lightOctreeWordCount = item->x4_octTree->x14_bitmapWordCount;
|
lightOctreeWordCount = item->x4_octTree->x14_bitmapWordCount;
|
||||||
lightOctreeWords = item->x1c_lightOctreeWords.data();
|
lightOctreeWords = item->x1c_lightOctreeWords.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
float lightRads[4] = {-1.f, -1.f, -1.f, -1.f};
|
std::array<float, 4> lightRads{-1.f, -1.f, -1.f, -1.f};
|
||||||
CLight* lightRefs[4] = {};
|
std::array<CLight*, 4> lightRefs{};
|
||||||
auto it = x300_dynamicLights.begin();
|
auto it = x300_dynamicLights.begin();
|
||||||
for (int i = 0; i < 4 && it != x300_dynamicLights.end(); ++it, lightOctreeWords += lightOctreeWordCount) {
|
for (size_t i = 0; i < thisLights.size() && it != x300_dynamicLights.end();
|
||||||
|
++it, lightOctreeWords += lightOctreeWordCount) {
|
||||||
CLight& refLight = *it;
|
CLight& refLight = *it;
|
||||||
if (lightOctreeWords && !TestBit(lightOctreeWords, model.x44_areaInstanceIdx))
|
if (lightOctreeWords && !TestBit(lightOctreeWords, model.x44_areaInstanceIdx)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float radius = model.x20_aabb.intersectionRadius(zeus::CSphere(refLight.GetPosition(), refLight.GetRadius()));
|
const float radius =
|
||||||
|
model.x20_aabb.intersectionRadius(zeus::CSphere(refLight.GetPosition(), refLight.GetRadius()));
|
||||||
|
|
||||||
bool foundLight = false;
|
bool foundLight = false;
|
||||||
for (int j = 0; j < i; ++j) {
|
for (size_t j = 0; j < i; ++j) {
|
||||||
if (lightRefs[j] == &refLight)
|
if (lightRefs[j] == &refLight) {
|
||||||
continue;
|
continue;
|
||||||
if (radius < 0.f)
|
}
|
||||||
|
if (radius < 0.f) {
|
||||||
break;
|
break;
|
||||||
if (lightRads[j] <= radius)
|
}
|
||||||
|
if (lightRads[j] <= radius) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
lightRads[j] = radius;
|
lightRads[j] = radius;
|
||||||
thisLights.push_back(refLight);
|
thisLights.push_back(refLight);
|
||||||
foundLight = true;
|
foundLight = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundLight)
|
if (foundLight) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
lightRads[i] = radius;
|
lightRads[i] = radius;
|
||||||
if (radius < 0.f)
|
if (radius < 0.f) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
lightRefs[i] = &refLight;
|
lightRefs[i] = &refLight;
|
||||||
thisLights.push_back(refLight);
|
thisLights.push_back(refLight);
|
||||||
++i;
|
++i;
|
||||||
|
@ -301,23 +324,8 @@ void CBooRenderer::HandleUnsortedModel(CAreaListItem* item, CBooModel& model, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct FogVolumeControl {
|
void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, size_t numPlanes, const zeus::CVector3f* verts,
|
||||||
|
size_t numVerts, size_t iteration, size_t level, CFogVolumePlaneShader& fogVol) {
|
||||||
u32 xfc_[12][2] = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6}, {6, 4}, {0, 4}, {1, 5}, {3, 7}, {2, 6}};
|
|
||||||
u32 x15c_[8] = {};
|
|
||||||
// GXVtxDescList x17c_; {{POS, DIRECT}, {TEX0, DIRECT}}
|
|
||||||
|
|
||||||
} s_FogVolumeCtrl = {};
|
|
||||||
|
|
||||||
static const int OrthogonalAxis[3][2] = {{1, 2}, {0, 2}, {0, 1}};
|
|
||||||
|
|
||||||
static float GetPlaneInterpolant(const zeus::CPlane& plane, const zeus::CVector3f& vert1,
|
|
||||||
const zeus::CVector3f& vert2) {
|
|
||||||
return zeus::clamp(0.f, -plane.pointToPlaneDist(vert1) / (vert2 - vert1).dot(plane.normal()), 1.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, const zeus::CVector3f* verts, int numVerts,
|
|
||||||
int iteration, int level, CFogVolumePlaneShader& fogVol) {
|
|
||||||
if (level == iteration) {
|
if (level == iteration) {
|
||||||
CalcDrawFogFan(planes, numPlanes, verts, numVerts, iteration, level + 1, fogVol);
|
CalcDrawFogFan(planes, numPlanes, verts, numVerts, iteration, level + 1, fogVol);
|
||||||
return;
|
return;
|
||||||
|
@ -329,48 +337,56 @@ void CBooRenderer::CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, con
|
||||||
}
|
}
|
||||||
|
|
||||||
const zeus::CPlane& plane = planes[level];
|
const zeus::CPlane& plane = planes[level];
|
||||||
u32 insidePlaneCount = 0;
|
size_t insidePlaneCount = 0;
|
||||||
bool outsidePlane[20];
|
std::array<bool, 20> outsidePlane;
|
||||||
for (int i = 0; i < numVerts; ++i)
|
for (size_t i = 0; i < numVerts; ++i) {
|
||||||
outsidePlane[insidePlaneCount++] = plane.normal().dot(verts[i]) < plane.d();
|
outsidePlane[insidePlaneCount++] = plane.normal().dot(verts[i]) < plane.d();
|
||||||
|
}
|
||||||
|
|
||||||
u32 numUseVerts = 0;
|
size_t numUseVerts = 0;
|
||||||
zeus::CVector3f useVerts[20];
|
std::array<zeus::CVector3f, 20> useVerts;
|
||||||
for (int i = 0; i < numVerts; ++i) {
|
for (size_t i = 0; i < numVerts; ++i) {
|
||||||
int nextIdx = (i + 1) % numVerts;
|
const size_t nextIdx = (i + 1) % numVerts;
|
||||||
int insidePair = int(outsidePlane[i]) | (int(outsidePlane[nextIdx]) << 1);
|
const int insidePair = int(outsidePlane[i]) | (int(outsidePlane[nextIdx]) << 1);
|
||||||
if (!(insidePair & 0x1))
|
if ((insidePair & 0x1) == 0) {
|
||||||
useVerts[numUseVerts++] = verts[i];
|
useVerts[numUseVerts++] = verts[i];
|
||||||
|
}
|
||||||
if (insidePair == 1 || insidePair == 2) {
|
if (insidePair == 1 || insidePair == 2) {
|
||||||
/* Inside/outside transition; clip verts to other plane boundary */
|
/* Inside/outside transition; clip verts to other plane boundary */
|
||||||
const zeus::CVector3f vert1 = verts[i];
|
const zeus::CVector3f vert1 = verts[i];
|
||||||
const zeus::CVector3f vert2 = verts[nextIdx];
|
const zeus::CVector3f vert2 = verts[nextIdx];
|
||||||
float interp = GetPlaneInterpolant(plane, vert1, vert2);
|
const float interp = GetPlaneInterpolant(plane, vert1, vert2);
|
||||||
if (interp > 0.f || interp < 1.f)
|
if (interp > 0.f || interp < 1.f) {
|
||||||
useVerts[numUseVerts++] = (vert1 * (1.f - interp)) + (vert2 * interp);
|
useVerts[numUseVerts++] = (vert1 * (1.f - interp)) + (vert2 * interp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (numUseVerts >= 3)
|
if (numUseVerts < 3) {
|
||||||
CalcDrawFogFan(planes, numPlanes, useVerts, numUseVerts, iteration, level + 1, fogVol);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalcDrawFogFan(planes, numPlanes, useVerts.data(), numUseVerts, iteration, level + 1, fogVol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration,
|
void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration,
|
||||||
const zeus::CVector3f& center, float longestAxis, CFogVolumePlaneShader& fogVol) {
|
const zeus::CVector3f& center, float longestAxis, CFogVolumePlaneShader& fogVol) {
|
||||||
u32 vertCount = 0;
|
u32 vertCount = 0;
|
||||||
zeus::CVector3d verts[4];
|
std::array<zeus::CVector3d, 4> verts;
|
||||||
u32 vert2Count = 0;
|
u32 vert2Count = 0;
|
||||||
zeus::CVector3f verts2[4];
|
std::array<zeus::CVector3f, 4> verts2;
|
||||||
const zeus::CPlane& plane = planes[iteration];
|
const zeus::CPlane& plane = planes[iteration];
|
||||||
int longestNormAxis = std::fabs(plane[1]) > std::fabs(plane[0]);
|
int longestNormAxis = std::fabs(plane[1]) > std::fabs(plane[0]);
|
||||||
if (std::fabs(plane[2]) > std::fabs(plane[longestNormAxis]))
|
if (std::fabs(plane[2]) > std::fabs(plane[longestNormAxis])) {
|
||||||
longestNormAxis = 2;
|
longestNormAxis = 2;
|
||||||
|
}
|
||||||
|
|
||||||
zeus::CVector3d pointOnPlane = center - (plane.pointToPlaneDist(center) * plane.normal());
|
const zeus::CVector3d pointOnPlane = center - (plane.pointToPlaneDist(center) * plane.normal());
|
||||||
|
|
||||||
float deltaSign = plane[longestNormAxis] >= 0.f ? -1.f : 1.f;
|
float deltaSign = plane[longestNormAxis] >= 0.f ? -1.f : 1.f;
|
||||||
if (longestNormAxis == 1)
|
if (longestNormAxis == 1) {
|
||||||
deltaSign = -deltaSign;
|
deltaSign = -deltaSign;
|
||||||
|
}
|
||||||
|
|
||||||
zeus::CVector3d vec1;
|
zeus::CVector3d vec1;
|
||||||
zeus::CVector3d vec2;
|
zeus::CVector3d vec2;
|
||||||
|
@ -383,11 +399,12 @@ void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int
|
||||||
verts[vertCount++] = pointOnPlane + vec1 + vec2;
|
verts[vertCount++] = pointOnPlane + vec1 + vec2;
|
||||||
verts[vertCount++] = pointOnPlane - vec1 + vec2;
|
verts[vertCount++] = pointOnPlane - vec1 + vec2;
|
||||||
|
|
||||||
zeus::CVector3d planeNormal = plane.normal();
|
const zeus::CVector3d planeNormal = plane.normal();
|
||||||
for (const zeus::CVector3d& vert : verts)
|
for (const zeus::CVector3d& vert : verts) {
|
||||||
verts2[vert2Count++] = vert - (planeNormal * zeus::CVector3f(planeNormal.dot(vert) - plane.d()));
|
verts2[vert2Count++] = vert - (planeNormal * zeus::CVector3f(planeNormal.dot(vert) - plane.d()));
|
||||||
|
}
|
||||||
|
|
||||||
CalcDrawFogFan(planes, numPlanes, verts2, vert2Count, iteration, 0, fogVol);
|
CalcDrawFogFan(planes, numPlanes, verts2.data(), vert2Count, iteration, 0, fogVol);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
|
void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
|
||||||
|
@ -397,23 +414,26 @@ void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel*
|
||||||
if (pass == 0) {
|
if (pass == 0) {
|
||||||
zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx);
|
zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx);
|
||||||
zeus::CUnitVector3f viewNormal(viewMtx.basis[1]);
|
zeus::CUnitVector3f viewNormal(viewMtx.basis[1]);
|
||||||
zeus::CPlane planes[7] = {{zeus::skRight, xfAABB.min.x()},
|
const std::array<zeus::CPlane, 7> planes{{
|
||||||
|
{zeus::skRight, xfAABB.min.x()},
|
||||||
{zeus::skLeft, -xfAABB.max.x()},
|
{zeus::skLeft, -xfAABB.max.x()},
|
||||||
{zeus::skForward, xfAABB.min.y()},
|
{zeus::skForward, xfAABB.min.y()},
|
||||||
{zeus::skBack, -xfAABB.max.y()},
|
{zeus::skBack, -xfAABB.max.y()},
|
||||||
{zeus::skUp, xfAABB.min.z()},
|
{zeus::skUp, xfAABB.min.z()},
|
||||||
{zeus::skDown, -xfAABB.max.z()},
|
{zeus::skDown, -xfAABB.max.z()},
|
||||||
{viewNormal, viewNormal.dot(viewMtx.origin) + 0.2f + 0.1f}};
|
{viewNormal, viewNormal.dot(viewMtx.origin) + 0.2f + 0.1f},
|
||||||
|
}};
|
||||||
|
|
||||||
CGraphics::SetModelMatrix(zeus::CTransform());
|
CGraphics::SetModelMatrix(zeus::CTransform());
|
||||||
|
|
||||||
float longestAxis = std::max(std::max(xfAABB.max.x() - xfAABB.min.x(), xfAABB.max.y() - xfAABB.min.y()),
|
const float longestAxis = std::max(std::max(xfAABB.max.x() - xfAABB.min.x(), xfAABB.max.y() - xfAABB.min.y()),
|
||||||
xfAABB.max.z() - xfAABB.min.z()) *
|
xfAABB.max.z() - xfAABB.min.z()) *
|
||||||
2.f;
|
2.f;
|
||||||
|
|
||||||
fvs->reset(7 * 6);
|
fvs->reset(7 * 6);
|
||||||
for (int i = 0; i < 7; ++i)
|
for (size_t i = 0; i < planes.size(); ++i) {
|
||||||
DrawFogSlices(planes, 7, i, xfAABB.center(), longestAxis, *fvs);
|
DrawFogSlices(planes.data(), planes.size(), i, xfAABB.center(), longestAxis, *fvs);
|
||||||
|
}
|
||||||
fvs->draw(0);
|
fvs->draw(0);
|
||||||
} else {
|
} else {
|
||||||
fvs->draw(pass);
|
fvs->draw(pass);
|
||||||
|
@ -458,45 +478,47 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
|
||||||
const CSkinnedModel* sModel) {
|
const CSkinnedModel* sModel) {
|
||||||
SCOPED_GRAPHICS_DEBUG_GROUP("CBooRenderer::ReallyRenderFogVolume", zeus::skPurple);
|
SCOPED_GRAPHICS_DEBUG_GROUP("CBooRenderer::ReallyRenderFogVolume", zeus::skPurple);
|
||||||
zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(false);
|
zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(false);
|
||||||
zeus::CVector4f points[8];
|
std::array<zeus::CVector4f, 8> points;
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (size_t i = 0; i < points.size(); ++i) {
|
||||||
zeus::CVector3f xfPt = CGraphics::g_GXModelView * aabb.getPoint(i);
|
const zeus::CVector3f xfPt = CGraphics::g_GXModelView * aabb.getPoint(i);
|
||||||
points[i] = proj * zeus::CVector4f(xfPt);
|
points[i] = proj * zeus::CVector4f(xfPt);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CVector2i vpMax(0, 0);
|
zeus::CVector2i vpMax(0, 0);
|
||||||
zeus::CVector2i vpMin(g_Viewport.x8_width, g_Viewport.xc_height);
|
zeus::CVector2i vpMin(g_Viewport.x8_width, g_Viewport.xc_height);
|
||||||
|
|
||||||
for (int i = 0; i < 20; ++i) {
|
for (size_t i = 0; i < 20; ++i) {
|
||||||
zeus::CVector3f overW;
|
zeus::CVector3f overW;
|
||||||
if (i < 8) {
|
if (i < points.size()) {
|
||||||
overW = points[i].toVec3f() * (1.f / points[i].w());
|
overW = points[i].toVec3f() * (1.f / points[i].w());
|
||||||
} else {
|
} else {
|
||||||
const zeus::CVector4f& pt1 = points[s_FogVolumeCtrl.xfc_[i - 8][0]];
|
const zeus::CVector4f& pt1 = points[s_FogVolumeCtrl.xfc_[i - 8][0]];
|
||||||
const zeus::CVector4f& pt2 = points[s_FogVolumeCtrl.xfc_[i - 8][1]];
|
const zeus::CVector4f& pt2 = points[s_FogVolumeCtrl.xfc_[i - 8][1]];
|
||||||
|
|
||||||
bool eq1 = (pt1.z() / pt1.w()) == 1.f;
|
const bool eq1 = (pt1.z() / pt1.w()) == 1.f;
|
||||||
bool eq2 = (pt2.z() / pt2.w()) == 1.f;
|
const bool eq2 = (pt2.z() / pt2.w()) == 1.f;
|
||||||
if (eq1 == eq2)
|
if (eq1 == eq2) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float interp = -(pt1.w() - 1.f) / (pt2.w() - pt1.w());
|
const float interp = -(pt1.w() - 1.f) / (pt2.w() - pt1.w());
|
||||||
if (interp <= 0.f || interp >= 1.f)
|
if (interp <= 0.f || interp >= 1.f) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float wRecip = 1.f / (interp * (pt2.w() - pt1.w()) + pt1.w());
|
const float wRecip = 1.f / (interp * (pt2.w() - pt1.w()) + pt1.w());
|
||||||
zeus::CVector3f pt1_3 = pt1.toVec3f();
|
const zeus::CVector3f pt1_3 = pt1.toVec3f();
|
||||||
zeus::CVector3f pt2_3 = pt2.toVec3f();
|
const zeus::CVector3f pt2_3 = pt2.toVec3f();
|
||||||
overW = (pt1_3 + interp * (pt2_3 - pt1_3)) * wRecip;
|
overW = (pt1_3 + interp * (pt2_3 - pt1_3)) * wRecip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (overW.z > 1.001f)
|
// if (overW.z > 1.001f)
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
int vpX = zeus::clamp(0, int(g_Viewport.x8_width * overW.x() * 0.5f + (g_Viewport.x8_width / 2)),
|
const int vpX = zeus::clamp(0, int(g_Viewport.x8_width * overW.x() * 0.5f + (g_Viewport.x8_width / 2)),
|
||||||
int(g_Viewport.x8_width));
|
int(g_Viewport.x8_width));
|
||||||
int vpY = zeus::clamp(0, int(g_Viewport.xc_height * overW.y() * 0.5f + (g_Viewport.xc_height / 2)),
|
const int vpY = zeus::clamp(0, int(g_Viewport.xc_height * overW.y() * 0.5f + (g_Viewport.xc_height / 2)),
|
||||||
int(g_Viewport.xc_height));
|
int(g_Viewport.xc_height));
|
||||||
vpMax.x = std::max(vpMax.x, vpX);
|
vpMax.x = std::max(vpMax.x, vpX);
|
||||||
vpMin.x = std::min(vpMin.x, vpX);
|
vpMin.x = std::min(vpMin.x, vpX);
|
||||||
|
@ -555,11 +577,11 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx) {
|
void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
u16 data[FOGVOL_RAMP_RES][FOGVOL_RAMP_RES] = {};
|
std::array<std::array<u16, FOGVOL_RAMP_RES>, FOGVOL_RAMP_RES> data{};
|
||||||
for (int y = 0; y < FOGVOL_RAMP_RES; ++y) {
|
for (size_t y = 0; y < data.size(); ++y) {
|
||||||
for (int x = 0; x < FOGVOL_RAMP_RES; ++x) {
|
for (size_t x = 0; x < data[y].size(); ++x) {
|
||||||
int tmp = y << 16 | x << 8 | 0x7f;
|
const int tmp = int(y << 16 | x << 8 | 0x7f);
|
||||||
double a =
|
const double a =
|
||||||
zeus::clamp(0.0,
|
zeus::clamp(0.0,
|
||||||
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
|
(-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) *
|
||||||
3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
|
3.0 / (FOGVOL_FAR - FOGVOL_NEAR),
|
||||||
|
@ -569,21 +591,21 @@ void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context&
|
||||||
}
|
}
|
||||||
x1b8_fogVolumeRamp =
|
x1b8_fogVolumeRamp =
|
||||||
ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, boo::TextureFormat::I16, boo::TextureClampMode::Repeat,
|
ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, boo::TextureFormat::I16, boo::TextureClampMode::Repeat,
|
||||||
data[0], FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2);
|
data[0].data(), FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx) {
|
void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
u8 data[SPHERE_RAMP_RES][SPHERE_RAMP_RES] = {};
|
std::array<std::array<u8, SPHERE_RAMP_RES>, SPHERE_RAMP_RES> data{};
|
||||||
float halfRes = SPHERE_RAMP_RES / 2.f;
|
constexpr float halfRes = SPHERE_RAMP_RES / 2.f;
|
||||||
for (int y = 0; y < SPHERE_RAMP_RES; ++y) {
|
for (size_t y = 0; y < data.size(); ++y) {
|
||||||
for (int x = 0; x < SPHERE_RAMP_RES; ++x) {
|
for (size_t x = 0; x < data[y].size(); ++x) {
|
||||||
zeus::CVector2f vec((x - halfRes) / halfRes, (y - halfRes) / halfRes);
|
const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes);
|
||||||
data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x220_sphereRamp = ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, boo::TextureFormat::I8,
|
x220_sphereRamp =
|
||||||
boo::TextureClampMode::ClampToEdge, data[0],
|
ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, boo::TextureFormat::I8,
|
||||||
SPHERE_RAMP_RES * SPHERE_RAMP_RES);
|
boo::TextureClampMode::ClampToEdge, data[0].data(), SPHERE_RAMP_RES * SPHERE_RAMP_RES);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx) {
|
void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
|
@ -624,18 +646,21 @@ void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::ObjToken<boo::ITexture> CBooRenderer::GetColorTexture(const zeus::CColor& color) {
|
boo::ObjToken<boo::ITexture> CBooRenderer::GetColorTexture(const zeus::CColor& color) {
|
||||||
auto search = m_colorTextures.find(color);
|
const auto search = m_colorTextures.find(color);
|
||||||
if (search != m_colorTextures.end())
|
if (search != m_colorTextures.end()) {
|
||||||
return search->second;
|
return search->second;
|
||||||
u8 pixel[4];
|
}
|
||||||
|
|
||||||
|
std::array<u8, 4> pixel;
|
||||||
color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]);
|
color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]);
|
||||||
boo::ObjToken<boo::ITexture> tex;
|
boo::ObjToken<boo::ITexture> tex;
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, pixel.data(),
|
||||||
boo::TextureClampMode::Repeat, pixel, 4).get();
|
pixel.size())
|
||||||
|
.get();
|
||||||
return true;
|
return true;
|
||||||
} BooTrace);
|
} BooTrace);
|
||||||
m_colorTextures.insert(std::make_pair(color, tex));
|
m_colorTextures.emplace(color, tex);
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,15 +688,18 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac)
|
||||||
m_staticEntropy = store.GetObj("RandomStaticEntropy");
|
m_staticEntropy = store.GetObj("RandomStaticEntropy");
|
||||||
|
|
||||||
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||||
u8 clearPixel[] = {0, 0, 0, 0};
|
constexpr std::array<u8, 4> clearPixel{0, 0, 0, 0};
|
||||||
m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
|
||||||
boo::TextureClampMode::Repeat, clearPixel, 4).get();
|
clearPixel.data(), clearPixel.size())
|
||||||
u8 blackPixel[] = {0, 0, 0, 255};
|
.get();
|
||||||
m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
constexpr std::array<u8, 4> blackPixel{0, 0, 0, 255};
|
||||||
boo::TextureClampMode::Repeat, blackPixel, 4).get();
|
m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
|
||||||
u8 whitePixel[] = {255, 255, 255, 255};
|
blackPixel.data(), blackPixel.size())
|
||||||
m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8,
|
.get();
|
||||||
boo::TextureClampMode::Repeat, whitePixel, 4).get();
|
constexpr std::array<u8, 4> whitePixel{255, 255, 255, 255};
|
||||||
|
m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat,
|
||||||
|
whitePixel.data(), whitePixel.size())
|
||||||
|
.get();
|
||||||
|
|
||||||
GenerateFogVolumeRampTex(ctx);
|
GenerateFogVolumeRampTex(ctx);
|
||||||
GenerateSphereRampTex(ctx);
|
GenerateSphereRampTex(ctx);
|
||||||
|
@ -708,7 +736,7 @@ void CBooRenderer::AddWorldSurfaces(CBooModel& model) {
|
||||||
std::list<CBooRenderer::CAreaListItem>::iterator
|
std::list<CBooRenderer::CAreaListItem>::iterator
|
||||||
CBooRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {
|
CBooRenderer::FindStaticGeometry(const std::vector<CMetroidModelInstance>* geometry) {
|
||||||
return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(),
|
return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(),
|
||||||
[&](CAreaListItem& item) -> bool { return item.x0_geometry == geometry; });
|
[&](const CAreaListItem& item) { return item.x0_geometry == geometry; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry,
|
void CBooRenderer::AddStaticGeometry(const std::vector<CMetroidModelInstance>* geometry,
|
||||||
|
|
|
@ -176,10 +176,10 @@ class CBooRenderer final : public IRenderer {
|
||||||
void ActivateLightsForModel(CAreaListItem* item, CBooModel& model);
|
void ActivateLightsForModel(CAreaListItem* item, CBooModel& model);
|
||||||
void RenderBucketItems(CAreaListItem* item);
|
void RenderBucketItems(CAreaListItem* item);
|
||||||
void HandleUnsortedModel(CAreaListItem* item, CBooModel& model, const CModelFlags& flags);
|
void HandleUnsortedModel(CAreaListItem* item, CBooModel& model, const CModelFlags& flags);
|
||||||
static void CalcDrawFogFan(const zeus::CPlane* planes, int numPlanes, const zeus::CVector3f* verts, int numVerts,
|
static void CalcDrawFogFan(const zeus::CPlane* planes, size_t numPlanes, const zeus::CVector3f* verts,
|
||||||
int iteration, int level, CFogVolumePlaneShader& fogVol);
|
size_t numVerts, size_t iteration, size_t level, CFogVolumePlaneShader& fogVol);
|
||||||
static void DrawFogSlices(const zeus::CPlane* planes, int numPlanes, int iteration, const zeus::CVector3f& center,
|
static void DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration,
|
||||||
float delta, CFogVolumePlaneShader& fogVol);
|
const zeus::CVector3f& center, float delta, CFogVolumePlaneShader& fogVol);
|
||||||
static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
|
static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx,
|
||||||
const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass,
|
const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass,
|
||||||
CFogVolumePlaneShader* fvs);
|
CFogVolumePlaneShader* fvs);
|
||||||
|
|
Loading…
Reference in New Issue