/* =========================================================================== 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 . =========================================================================== */ // 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)); } }