mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-31 00:45:24 -04:00
247 lines
6.1 KiB
C++
247 lines
6.1 KiB
C++
/**
|
|
* J3DDrawBuffer.cpp
|
|
*
|
|
*/
|
|
|
|
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
|
|
|
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
|
|
#include "JSystem/J3DGraphBase/J3DMaterial.h"
|
|
#include "JSystem/JKernel/JKRHeap.h"
|
|
#include "tracy/Tracy.hpp"
|
|
|
|
void J3DDrawBuffer::calcZRatio() {
|
|
mZRatio = (mZFar - mZNear) / (f32)mEntryTableSize;
|
|
}
|
|
|
|
void J3DDrawBuffer::initialize() {
|
|
mDrawMode = J3DDrawBufDrawMode_Head;
|
|
mSortMode = J3DDrawBufSortMode_Mat;
|
|
mZNear = 1.0f;
|
|
mZFar = 10000.0f;
|
|
mpZMtx = NULL;
|
|
mpCallBackPacket = NULL;
|
|
mEntryTableSize = 0x20;
|
|
calcZRatio();
|
|
}
|
|
|
|
int J3DDrawBuffer::allocBuffer(u32 size) {
|
|
mpBuffer = JKR_NEW_ARRAY_ARGS(J3DPacket*, size, 0x20);
|
|
if (mpBuffer == NULL)
|
|
return kJ3DError_Alloc;
|
|
|
|
mEntryTableSize = size;
|
|
|
|
frameInit();
|
|
calcZRatio();
|
|
return kJ3DError_Success;
|
|
}
|
|
|
|
J3DDrawBuffer::~J3DDrawBuffer() {
|
|
frameInit();
|
|
|
|
JKR_DELETE_ARRAY(mpBuffer);
|
|
mpBuffer = NULL;
|
|
}
|
|
|
|
void J3DDrawBuffer::frameInit() {
|
|
u32 bufSize = mEntryTableSize;
|
|
for (u32 i = 0; i < bufSize; i++)
|
|
mpBuffer[i] = NULL;
|
|
|
|
mpCallBackPacket = NULL;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryMatSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(122, pMatPacket != NULL);
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
if (pMatPacket->isChanged()) {
|
|
pMatPacket->setNextPacket(mpBuffer[0]);
|
|
mpBuffer[0] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
J3DTexture* pTexture = j3dSys.getTexture();
|
|
u16 texNo = pMatPacket->getMaterial()->getTexNo(0);
|
|
J3D_ASSERT_NULLPTR(150, pTexture != NULL);
|
|
|
|
u32 hash;
|
|
if (texNo == 0xFFFF) {
|
|
hash = 0;
|
|
} else {
|
|
hash = ((uintptr_t)pTexture->getResTIMG(texNo) + pTexture->getResTIMG(texNo)->imageOffset) >> 5;
|
|
}
|
|
u32 slot = hash & (mEntryTableSize - 1);
|
|
|
|
if (mpBuffer[slot] == NULL) {
|
|
mpBuffer[slot] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
J3DMatPacket* packet;
|
|
for (packet = (J3DMatPacket*)mpBuffer[slot]; packet != NULL; packet = (J3DMatPacket*)packet->getNextPacket())
|
|
{
|
|
if (packet->isSame(pMatPacket)) {
|
|
packet->addShapePacket(pMatPacket->getShapePacket());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
pMatPacket->setNextPacket(mpBuffer[slot]);
|
|
mpBuffer[slot] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryMatAnmSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(199, pMatPacket != NULL);
|
|
|
|
J3DMaterialAnm* pMaterialAnm = pMatPacket->mpMaterialAnm;
|
|
u32 slot = (uintptr_t)pMaterialAnm & (mEntryTableSize - 1);
|
|
|
|
if (pMaterialAnm == NULL) {
|
|
return entryMatSort(pMatPacket);
|
|
}
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
if (mpBuffer[slot] == NULL) {
|
|
mpBuffer[slot] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
J3DMatPacket* packet;
|
|
for (packet = (J3DMatPacket*)mpBuffer[slot]; packet != NULL; packet = (J3DMatPacket*)packet->getNextPacket())
|
|
{
|
|
if (packet->mpMaterialAnm == pMaterialAnm) {
|
|
packet->addShapePacket(pMatPacket->getShapePacket());
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
pMatPacket->setNextPacket(mpBuffer[slot]);
|
|
mpBuffer[slot] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryZSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(257, pMatPacket != NULL);
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
Vec tmp;
|
|
tmp.x = mpZMtx[0][3];
|
|
tmp.y = mpZMtx[1][3];
|
|
tmp.z = mpZMtx[2][3];
|
|
|
|
f32 value = -J3DCalcZValue(j3dSys.getViewMtx(), tmp);
|
|
|
|
u32 index;
|
|
if (mZNear + mZRatio < value) {
|
|
if (mZFar - mZRatio > value) {
|
|
index = value / mZRatio;
|
|
} else {
|
|
index = mEntryTableSize - 1;
|
|
}
|
|
} else {
|
|
index = 0;
|
|
}
|
|
|
|
index = (mEntryTableSize - 1) - index;
|
|
pMatPacket->setNextPacket(mpBuffer[index]);
|
|
mpBuffer[index] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryModelSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(316, pMatPacket != NULL);
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
if (mpCallBackPacket != NULL) {
|
|
mpCallBackPacket->addChildPacket(pMatPacket);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryInvalidSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(343, pMatPacket != NULL);
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
if (mpCallBackPacket != NULL) {
|
|
mpCallBackPacket->addChildPacket(pMatPacket->getShapePacket());
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryNonSort(J3DMatPacket* pMatPacket) {
|
|
J3D_ASSERT_NULLPTR(370, pMatPacket != NULL);
|
|
|
|
pMatPacket->drawClear();
|
|
pMatPacket->getShapePacket()->drawClear();
|
|
|
|
pMatPacket->setNextPacket(mpBuffer[0]);
|
|
mpBuffer[0] = pMatPacket;
|
|
return 1;
|
|
}
|
|
|
|
int J3DDrawBuffer::entryImm(J3DPacket* pPacket, u16 index) {
|
|
J3D_ASSERT_NULLPTR(394, pPacket != NULL);
|
|
J3D_ASSERT_RANGE(395, index < mEntryTableSize);
|
|
|
|
pPacket->setNextPacket(mpBuffer[index]);
|
|
mpBuffer[index] = pPacket;
|
|
return 1;
|
|
}
|
|
|
|
J3DDrawBuffer::sortFunc J3DDrawBuffer::sortFuncTable[6] = {
|
|
&J3DDrawBuffer::entryMatSort, &J3DDrawBuffer::entryMatAnmSort, &J3DDrawBuffer::entryZSort,
|
|
&J3DDrawBuffer::entryModelSort, &J3DDrawBuffer::entryInvalidSort, &J3DDrawBuffer::entryNonSort,
|
|
};
|
|
|
|
J3DDrawBuffer::drawFunc J3DDrawBuffer::drawFuncTable[2] = {
|
|
&J3DDrawBuffer::drawHead,
|
|
&J3DDrawBuffer::drawTail,
|
|
};
|
|
|
|
int J3DDrawBuffer::entryNum;
|
|
|
|
void J3DDrawBuffer::draw() const {
|
|
J3D_ASSERT_RANGE(411, mDrawMode < J3DDrawBufDrawMode_MAX);
|
|
|
|
drawFunc func = drawFuncTable[mDrawMode];
|
|
(this->*func)();
|
|
}
|
|
|
|
void J3DDrawBuffer::drawHead() const {
|
|
ZoneScoped;
|
|
u32 size = mEntryTableSize;
|
|
J3DPacket** buf = mpBuffer;
|
|
|
|
for (u32 i = 0; i < size; i++) {
|
|
for (J3DPacket* packet = buf[i]; packet != NULL; packet = packet->getNextPacket()) {
|
|
packet->draw();
|
|
}
|
|
}
|
|
}
|
|
|
|
void J3DDrawBuffer::drawTail() const {
|
|
ZoneScoped;
|
|
for (int i = mEntryTableSize - 1; i >= 0; i--) {
|
|
for (J3DPacket* packet = mpBuffer[i]; packet != NULL; packet = packet->getNextPacket()) {
|
|
packet->draw();
|
|
}
|
|
}
|
|
}
|