thunderbrew/src/ui/CSimpleRender.cpp
2023-03-09 22:29:33 -06:00

169 lines
5.1 KiB
C++

#include "ui/CSimpleRender.hpp"
#include "gx/Buffer.hpp"
#include "gx/Device.hpp"
#include "gx/Draw.hpp"
#include "gx/Font.hpp"
#include "gx/Gx.hpp"
#include "gx/RenderState.hpp"
#include "gx/Shader.hpp"
#include "gx/Texture.hpp"
#include "gx/Transform.hpp"
#include "gx/Types.hpp"
#include "ui/CRenderBatch.hpp"
CGxShader* CSimpleRender::s_vertexShader[2];
void CSimpleRender::DrawBatch(CRenderBatch* batch) {
if (batch->m_texturelist.Count()) {
GxRsPush();
CGxShader* vs = g_theGxDevicePtr->StereoEnabled()
? CSimpleRender::s_vertexShader[1]
: CSimpleRender::s_vertexShader[0];
if (vs && vs->Valid()) {
GxRsSet(GxRs_VertexShader, vs);
C44Matrix viewProjMat;
GxXformViewProjNativeTranspose(viewProjMat);
GxShaderConstantsSet(GxSh_Vertex, 0, reinterpret_cast<float*>(&viewProjMat), 4);
} else {
GxRsSet(GxRs_Lighting, 0);
}
GxRsSet(GxRs_Fog, 0);
GxRsSet(GxRs_DepthTest, 0);
GxRsSet(GxRs_DepthWrite, 0);
CGxTex* textureID = nullptr;
EGxBlend alphaMode = GxBlends_Last;
CGxShader* ps = nullptr;
uint32_t idxCount = 0;
uint32_t posCount = 0;
for (int32_t i = 0; i < batch->m_texturelist.Count(); i++) {
auto mesh = &batch->m_texturelist[i];
auto dirty = 0;
if (mesh->textureID != textureID) {
textureID = mesh->textureID;
dirty = 1;
}
if (mesh->GetAlphaMode() != alphaMode) {
alphaMode = mesh->GetAlphaMode();
dirty = 1;
}
if (mesh->shader != ps) {
ps = mesh->shader;
dirty = 1;
}
CTexture* texture = mesh->texture;
CGxTex* gxTex = TextureGetGxTex(texture, 1, nullptr);
GxRsSet(GxRs_Texture0, gxTex);
GxRsSet(GxRs_BlendingMode, alphaMode);
GxRsSet(GxRs_PixelShader, ps);
// TODO
// - alphaRef
// TODO
// - geometry merging (CSimpleRender::s_mergeEnable)
posCount = mesh->posCount;
idxCount = mesh->idxCount;
CGxBuf* vertexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Vertex, 24, posCount);
char* vertexData = g_theGxDevicePtr->BufLock(vertexStream);
CGxVertexPCT* vertexBuf = reinterpret_cast<CGxVertexPCT*>(vertexData);
CGxBuf* indexStream = g_theGxDevicePtr->BufStream(GxPoolTarget_Index, 2, idxCount);
char* indexData = g_theGxDevicePtr->BufLock(indexStream);
uint16_t* indexBuf = reinterpret_cast<uint16_t*>(indexData);
if (mesh->indices) {
for (int32_t i = 0; i < mesh->posCount; i++) {
C3Vector* p = &mesh->position[i];
vertexBuf->p.x = p->x;
vertexBuf->p.y = p->y;
vertexBuf->p.z = p->z;
if (mesh->color) {
auto& color = mesh->color[i * mesh->colorCount >> 2];
if (GxCaps().m_colorFormat == GxCF_rgba) {
vertexBuf->c.r = color.b;
vertexBuf->c.g = color.g;
vertexBuf->c.b = color.r;
vertexBuf->c.a = color.a;
} else {
vertexBuf->c = color;
}
} else {
vertexBuf->c.r = 0xFF;
vertexBuf->c.g = 0xFF;
vertexBuf->c.b = 0xFF;
vertexBuf->c.a = 0xFF;
}
if (mesh->onAtlas) {
// TODO
} else {
C2Vector* tc = &mesh->texCoord[i];
vertexBuf->tc[0].x = tc->x;
vertexBuf->tc[0].y = tc->y;
}
vertexBuf++;
}
for (int32_t i = 0; i < mesh->idxCount; i++) {
*indexBuf = mesh->indices[i];
indexBuf++;
}
}
GxBufUnlock(vertexStream, 24 * posCount);
GxBufUnlock(indexStream, 2 * idxCount);
GxPrimVertexPtr(vertexStream, GxVBF_PCT);
GxPrimIndexPtr(indexStream);
CGxBatch batch;
batch.m_primType = GxPrim_Triangles;
batch.m_start = 0;
batch.m_count = 6;
batch.m_minIndex = 0;
batch.m_maxIndex = 3;
GxDraw(&batch, 1);
}
GxRsPop();
}
if (batch->m_stringbatch) {
GxuFontRenderBatch(batch->m_stringbatch);
}
for (auto callback = batch->m_callbacks.Head(); callback; callback = batch->m_callbacks.Link(callback)->Next()) {
callback->callback(callback->param);
}
}
void CSimpleRender::Init() {
g_theGxDevicePtr->ShaderCreate(
CSimpleRender::s_vertexShader,
GxSh_Vertex,
"Shaders\\Vertex",
"UI",
2
);
}