mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-02 08:42:45 +03:00
feat(gx): add locked vertex drawing functions
This commit is contained in:
parent
55a3bacbd0
commit
695e021621
@ -179,6 +179,8 @@ int32_t Buffer::s_vertexBufOffset[GxVertexBufferFormats_Last][GxVAs_Last] = {
|
|||||||
{ 0, -1, -1, 12, 24, 28, 32, 40, -1, -1, -1, -1, -1, -1 }
|
{ 0, -1, -1, 12, 24, 28, 32, 40, -1, -1, -1, -1, -1, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t Buffer::s_lockVertexCount = 0;
|
||||||
|
|
||||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat format, EGxVertexAttrib attrib) {
|
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat format, EGxVertexAttrib attrib) {
|
||||||
return Buffer::s_vertexBufOffset[format][attrib];
|
return Buffer::s_vertexBufOffset[format][attrib];
|
||||||
}
|
}
|
||||||
@ -204,6 +206,16 @@ void GxPrimIndexPtr(CGxBuf* buf) {
|
|||||||
g_theGxDevicePtr->PrimIndexPtr(buf);
|
g_theGxDevicePtr->PrimIndexPtr(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxPrimIndexPtr(uint32_t indexCount, const uint16_t* indices) {
|
||||||
|
auto buf = g_theGxDevicePtr->BufStream(GxPoolTarget_Index, 2, indexCount);
|
||||||
|
|
||||||
|
g_theGxDevicePtr->BufData(buf, indices, buf->m_itemCount * buf->m_itemSize, 0);
|
||||||
|
|
||||||
|
buf->unk1C = 1;
|
||||||
|
|
||||||
|
g_theGxDevicePtr->PrimIndexPtr(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void GxPrimVertexPtr(CGxBuf* buf, EGxVertexBufferFormat format) {
|
void GxPrimVertexPtr(CGxBuf* buf, EGxVertexBufferFormat format) {
|
||||||
auto desc = &Buffer::s_vertexBufDesc[format];
|
auto desc = &Buffer::s_vertexBufDesc[format];
|
||||||
|
|
||||||
@ -211,3 +223,223 @@ void GxPrimVertexPtr(CGxBuf* buf, EGxVertexBufferFormat format) {
|
|||||||
g_theGxDevicePtr->PrimVertexMask(desc->mask);
|
g_theGxDevicePtr->PrimVertexMask(desc->mask);
|
||||||
g_theGxDevicePtr->PrimVertexPtr(buf, format);
|
g_theGxDevicePtr->PrimVertexPtr(buf, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxPrimVertexPtr(uint32_t vertexCount, const C3Vector* pos, uint32_t posStride, const C3Vector* normal, uint32_t normalStride, const CImVector* color, uint32_t colorStride, const C2Vector* tex0, uint32_t tex0Stride, const C2Vector* tex1, uint32_t tex1Stride) {
|
||||||
|
// Select vertex buffer format based on given parameters
|
||||||
|
EGxVertexBufferFormat bufFmt = GxVBF_P;
|
||||||
|
|
||||||
|
if (pos != nullptr) {
|
||||||
|
if (normal != nullptr) {
|
||||||
|
if (color != nullptr) {
|
||||||
|
if (tex0 != nullptr) {
|
||||||
|
if (tex1 != nullptr) {
|
||||||
|
bufFmt = GxVBF_PNCT2;
|
||||||
|
} else {
|
||||||
|
bufFmt = GxVBF_PNCT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex1 == nullptr) {
|
||||||
|
bufFmt = GxVBF_PNC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex0 != nullptr) {
|
||||||
|
if (tex1 != nullptr) {
|
||||||
|
bufFmt = GxVBF_PNT2;
|
||||||
|
} else {
|
||||||
|
bufFmt = GxVBF_PNT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex1 == nullptr) {
|
||||||
|
bufFmt = GxVBF_PN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (color != nullptr) {
|
||||||
|
if (tex0 != nullptr) {
|
||||||
|
if (tex1 != nullptr) {
|
||||||
|
bufFmt = GxVBF_PCT2;
|
||||||
|
} else {
|
||||||
|
bufFmt = GxVBF_PCT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex1 == nullptr) {
|
||||||
|
bufFmt = GxVBF_PC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tex0 != nullptr) {
|
||||||
|
if (tex1 != nullptr) {
|
||||||
|
bufFmt = GxVBF_PT2;
|
||||||
|
} else {
|
||||||
|
bufFmt = GxVBF_PT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto vertexSize = Buffer::s_vertexBufDesc[bufFmt].size;
|
||||||
|
|
||||||
|
auto buf = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, vertexSize, vertexCount);
|
||||||
|
auto bufData = g_theGxDevicePtr->BufLock(buf);
|
||||||
|
|
||||||
|
C3Vector genericNormal = {};
|
||||||
|
CImVector genericColor = {};
|
||||||
|
C2Vector genericTexCoord0 = {};
|
||||||
|
C2Vector genericTexCoord1 = {};
|
||||||
|
|
||||||
|
C3Vector* writeNormal;
|
||||||
|
CImVector* writeColor;
|
||||||
|
C2Vector* writeTexCoord0;
|
||||||
|
C2Vector* writeTexCoord1;
|
||||||
|
|
||||||
|
uintptr_t writeNormalStride = normal != nullptr ? vertexSize : 0;
|
||||||
|
if (normal == nullptr) {
|
||||||
|
writeNormal = &genericNormal;
|
||||||
|
} else {
|
||||||
|
writeNormal = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(bufData) + uintptr_t(GxVertexAttribOffset(bufFmt, GxVA_Normal))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t writeColorStride = color != nullptr ? vertexSize : 0;
|
||||||
|
if (color == nullptr) {
|
||||||
|
writeColor = &genericColor;
|
||||||
|
} else {
|
||||||
|
writeColor = reinterpret_cast<CImVector*>(
|
||||||
|
uintptr_t(bufData) + uintptr_t(GxVertexAttribOffset(bufFmt, GxVA_Color0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t writeTexCoord0Stride = tex0 != nullptr ? vertexSize : 0;
|
||||||
|
if (tex0 == nullptr) {
|
||||||
|
writeTexCoord0 = &genericTexCoord0;
|
||||||
|
} else {
|
||||||
|
writeTexCoord0 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(bufData) + uintptr_t(GxVertexAttribOffset(bufFmt, GxVA_TexCoord0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t writeTexCoord1Stride = tex1 != nullptr ? vertexSize : 0;
|
||||||
|
if (tex1 == nullptr) {
|
||||||
|
writeTexCoord1 = &genericTexCoord1;
|
||||||
|
} else {
|
||||||
|
writeTexCoord1 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(bufData) + uintptr_t(GxVertexAttribOffset(bufFmt, GxVA_TexCoord1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normal == nullptr) {
|
||||||
|
normal = &genericNormal;
|
||||||
|
normalStride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (color == nullptr) {
|
||||||
|
color = &genericColor;
|
||||||
|
colorStride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex0 == nullptr) {
|
||||||
|
tex0 = &genericTexCoord0;
|
||||||
|
tex0Stride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex1 == nullptr) {
|
||||||
|
tex1 = &genericTexCoord1;
|
||||||
|
tex1Stride = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertexCount != 0) {
|
||||||
|
auto useRgba = GxCaps().m_colorFormat == GxCF_rgba;
|
||||||
|
|
||||||
|
C3Vector* writePos = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(bufData) + uintptr_t(GxVertexAttribOffset(bufFmt, GxVA_Position))
|
||||||
|
);
|
||||||
|
|
||||||
|
for (uint32_t v = 0; v < vertexCount; v++) {
|
||||||
|
*writePos = *pos;
|
||||||
|
pos = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(pos) + uintptr_t(posStride)
|
||||||
|
);
|
||||||
|
writePos = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(writePos) + uintptr_t(vertexSize)
|
||||||
|
);
|
||||||
|
|
||||||
|
*writeNormal = *normal;
|
||||||
|
normal = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(normal) + uintptr_t(normalStride)
|
||||||
|
);
|
||||||
|
writeNormal = reinterpret_cast<C3Vector*>(
|
||||||
|
uintptr_t(writeNormal) + writeNormalStride
|
||||||
|
);
|
||||||
|
|
||||||
|
if (useRgba) {
|
||||||
|
uint8_t rgba[4];
|
||||||
|
rgba[0] = color->r;
|
||||||
|
rgba[1] = color->g;
|
||||||
|
rgba[2] = color->b;
|
||||||
|
rgba[3] = color->a;
|
||||||
|
memcpy(writeColor, rgba, 4);
|
||||||
|
} else {
|
||||||
|
*writeColor = *color;
|
||||||
|
}
|
||||||
|
color = reinterpret_cast<CImVector*>(
|
||||||
|
uintptr_t(color) + colorStride
|
||||||
|
);
|
||||||
|
writeColor = reinterpret_cast<CImVector*>(
|
||||||
|
uintptr_t(writeColor) + writeColorStride
|
||||||
|
);
|
||||||
|
|
||||||
|
*writeTexCoord0 = *tex0;
|
||||||
|
tex0 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(tex0) + tex0Stride
|
||||||
|
);
|
||||||
|
writeTexCoord0 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(writeTexCoord0) + writeTexCoord0Stride
|
||||||
|
);
|
||||||
|
|
||||||
|
*writeTexCoord1 = *tex1;
|
||||||
|
tex1 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(tex1) + tex1Stride
|
||||||
|
);
|
||||||
|
writeTexCoord1 = reinterpret_cast<C2Vector*>(
|
||||||
|
uintptr_t(writeTexCoord1) + writeTexCoord1Stride
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GxBufUnlock(buf, vertexSize * vertexCount);
|
||||||
|
GxPrimVertexPtr(buf, bufFmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxPrimLockVertexPtrs(uint32_t vertexCount, const C3Vector* pos, uint32_t posStride, const C3Vector* normal, uint32_t normalStride, const CImVector* color, uint32_t colorStride, const unsigned char* bone, uint32_t boneStride, const C2Vector* tex0, uint32_t tex0Stride, const C2Vector* tex1, uint32_t tex1Stride) {
|
||||||
|
BLIZZARD_ASSERT(Buffer::s_lockVertexCount == 0);
|
||||||
|
Buffer::s_lockVertexCount = vertexCount;
|
||||||
|
|
||||||
|
GxPrimVertexPtr(vertexCount, pos, posStride, normal, normalStride, color, colorStride, tex0, tex0Stride, tex1, tex1Stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxDrawLockedElements(EGxPrim primType, uint32_t indexCount, const uint16_t* indices) {
|
||||||
|
if (Buffer::s_lockVertexCount == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GxPrimIndexPtr(indexCount, indices);
|
||||||
|
|
||||||
|
CGxBatch batch;
|
||||||
|
batch.m_primType = primType;
|
||||||
|
batch.m_minIndex = 0;
|
||||||
|
batch.m_maxIndex = Buffer::s_lockVertexCount - 1;
|
||||||
|
batch.m_start = 0;
|
||||||
|
batch.m_count = indexCount;
|
||||||
|
|
||||||
|
BLIZZARD_ASSERT(batch.m_count > 0);
|
||||||
|
|
||||||
|
g_theGxDevicePtr->Draw(&batch, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxPrimUnlockVertexPtrs() {
|
||||||
|
Buffer::s_lockVertexCount = 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ struct VertexBufDesc {
|
|||||||
namespace Buffer {
|
namespace Buffer {
|
||||||
extern VertexBufDesc s_vertexBufDesc[GxVertexBufferFormats_Last];
|
extern VertexBufDesc s_vertexBufDesc[GxVertexBufferFormats_Last];
|
||||||
extern int32_t s_vertexBufOffset[GxVertexBufferFormats_Last][GxVAs_Last];
|
extern int32_t s_vertexBufOffset[GxVertexBufferFormats_Last][GxVAs_Last];
|
||||||
|
extern uint32_t s_lockVertexCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
uint32_t GxVertexAttribOffset(EGxVertexBufferFormat, EGxVertexAttrib);
|
||||||
@ -33,6 +34,16 @@ CGxPool* GxPoolCreate(EGxPoolTarget, EGxPoolUsage, uint32_t, EGxPoolHintBits, ch
|
|||||||
|
|
||||||
void GxPrimIndexPtr(CGxBuf*);
|
void GxPrimIndexPtr(CGxBuf*);
|
||||||
|
|
||||||
|
void GxPrimIndexPtr(uint32_t indexCount, const uint16_t* indices);
|
||||||
|
|
||||||
void GxPrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
void GxPrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
||||||
|
|
||||||
|
void GxPrimVertexPtr(uint32_t vertexCount, const C3Vector* pos, uint32_t posStride, const C3Vector* normal, uint32_t normalStride, const CImVector* color, uint32_t colorStride, const C2Vector* tex0, uint32_t tex0Stride, const C2Vector* tex1, uint32_t tex1Stride);
|
||||||
|
|
||||||
|
void GxPrimLockVertexPtrs(uint32_t vertexCount, const C3Vector* pos, uint32_t posStride, const C3Vector* normal, uint32_t normalStride, const CImVector* color, uint32_t colorStride, const unsigned char* bone, uint32_t boneStride, const C2Vector* tex0, uint32_t tex0Stride, const C2Vector* tex1, uint32_t tex1Stride);
|
||||||
|
|
||||||
|
void GxDrawLockedElements(EGxPrim primType, uint32_t indexCount, const uint16_t* indices);
|
||||||
|
|
||||||
|
void GxPrimUnlockVertexPtrs();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user