cnq3/code/renderer/grp_geometry.cpp

113 lines
3.5 KiB
C++

/*
===========================================================================
Copyright (C) 2023-2024 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
Challenge Quake 3 is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Challenge Quake 3 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Challenge Quake 3. If not, see <https://www.gnu.org/licenses/>.
===========================================================================
*/
// Gameplay Rendering Pipeline - vertex and index buffer management
#include "grp_local.h"
void VertexBuffers::Create(const char* name, MemoryUsage::Id memoryUsage, uint32_t vertexCount)
{
totalCount = vertexCount;
BufferDesc desc = {};
desc.committedResource = true;
desc.initialState = ResourceStates::VertexBufferBit;
desc.memoryUsage = memoryUsage;
desc.name = va("%s position vertex", name);
desc.byteCount = vertexCount * sizeof(vec3_t);
buffers[BasePosition] = CreateBuffer(desc);
strides[BasePosition] = sizeof(vec3_t);
desc.name = va("%s normal vertex", name);
desc.byteCount = vertexCount * sizeof(vec3_t);
buffers[BaseNormal] = CreateBuffer(desc);
strides[BaseNormal] = sizeof(vec3_t);
for(uint32_t s = 0; s < MAX_SHADER_STAGES; ++s)
{
desc.name = va("%s tex coords #%d vertex", name, (int)s + 1);
desc.byteCount = vertexCount * sizeof(vec2_t);
buffers[BaseCount + s * StageCount + StageTexCoords] = CreateBuffer(desc);
strides[BaseCount + s * StageCount + StageTexCoords] = sizeof(vec2_t);
desc.name = va("%s color #%d vertex", name, (int)s + 1);
desc.byteCount = vertexCount * sizeof(color4ub_t);
buffers[BaseCount + s * StageCount + StageColors] = CreateBuffer(desc);
strides[BaseCount + s * StageCount + StageColors] = sizeof(color4ub_t);
}
}
void VertexBuffers::BeginUpload()
{
for(uint32_t b = 0; b < BufferCount; ++b)
{
mapped[b] = BeginBufferUpload(buffers[b]);
}
}
void VertexBuffers::EndUpload()
{
for(uint32_t b = 0; b < BufferCount; ++b)
{
EndBufferUpload(buffers[b]);
mapped[b] = NULL;
}
}
void VertexBuffers::Upload(uint32_t firstStage, uint32_t stageCount)
{
Q_assert(mapped[0] != NULL);
const uint32_t batchOffset = batchFirst + batchCount;
float* pos = (float*)mapped[BasePosition] + 3 * batchOffset;
for(int v = 0; v < tess.numVertexes; ++v)
{
pos[0] = tess.xyz[v][0];
pos[1] = tess.xyz[v][1];
pos[2] = tess.xyz[v][2];
pos += 3;
}
float* nor = (float*)mapped[BaseNormal] + 3 * batchOffset;
for(int v = 0; v < tess.numVertexes; ++v)
{
nor[0] = tess.normal[v][0];
nor[1] = tess.normal[v][1];
nor[2] = tess.normal[v][2];
nor += 3;
}
for(uint32_t s = 0; s < stageCount; ++s)
{
const stageVars_t& sv = tess.svars[s + firstStage];
uint8_t* const tcBuffer = mapped[BaseCount + s * StageCount + StageTexCoords];
float* tc = (float*)tcBuffer + 2 * batchOffset;
memcpy(tc, &sv.texcoords[0], tess.numVertexes * sizeof(vec2_t));
uint8_t* const colBuffer = mapped[BaseCount + s * StageCount + StageColors];
uint32_t* col = (uint32_t*)colBuffer + batchOffset;
memcpy(col, &sv.colors[0], tess.numVertexes * sizeof(color4ub_t));
}
}