optimize (part 1)

This commit is contained in:
MihailRis 2024-11-16 09:18:14 +03:00
parent 4400366719
commit b28bcf052b
5 changed files with 61 additions and 18 deletions

View File

@ -58,10 +58,9 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
if (vertexBuffer != nullptr && vertices != 0) {
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STATIC_DRAW);
}
else {
glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STREAM_DRAW);
} else {
glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW);
}
if (indexBuffer != nullptr && indices != 0) {
if (ibo == 0) glGenBuffers(1, &ibo);

View File

@ -498,6 +498,9 @@ SortingMeshData BlocksRenderer::renderTranslucent(
) {
SortingMeshData sortingMesh {{}};
AABB aabb {};
bool aabbInit = false;
size_t totalSize = 0;
for (const auto drawGroup : *content.drawGroups) {
int begin = beginEnds[drawGroup][0];
if (begin == 0) {
@ -557,21 +560,51 @@ SortingMeshData BlocksRenderer::renderTranslucent(
),
util::Buffer<float>(indexSize * VERTEX_SIZE)};
totalSize += entry.vertexData.size();
for (int j = 0; j < indexSize; j++) {
std::memcpy(
entry.vertexData.data() + j * VERTEX_SIZE,
vertexBuffer.get() + indexBuffer[j] * VERTEX_SIZE,
sizeof(float) * VERTEX_SIZE
);
entry.vertexData[j * VERTEX_SIZE + 0] += chunk->x * CHUNK_W + 0.5f;
entry.vertexData[j * VERTEX_SIZE + 1] += 0.5f;
entry.vertexData[j * VERTEX_SIZE + 2] += chunk->z * CHUNK_D + 0.5f;
float& vx = entry.vertexData[j * VERTEX_SIZE + 0];
float& vy = entry.vertexData[j * VERTEX_SIZE + 1];
float& vz = entry.vertexData[j * VERTEX_SIZE + 2];
if (!aabbInit) {
aabbInit = true;
aabb.a = aabb.b = {vx, vy, vz};
} else {
aabb.addPoint(glm::vec3(vx, vy, vz));
}
vx += chunk->x * CHUNK_W + 0.5f;
vy += 0.5f;
vz += chunk->z * CHUNK_D + 0.5f;
}
sortingMesh.entries.push_back(std::move(entry));
vertexOffset = 0;
indexOffset = indexSize = 0;
}
}
// additional powerful optimization
auto size = aabb.size();
if (glm::abs(size.y) < 0.01f && sortingMesh.entries.size() > 1 && false) {
SortingMeshEntry newEntry {
sortingMesh.entries[0].position,
util::Buffer<float>(totalSize)
};
size_t offset = 0;
for (const auto& entry : sortingMesh.entries) {
std::memcpy(
newEntry.vertexData.data() + offset,
entry.vertexData.data(), entry.vertexData.size() * sizeof(float)
);
offset += entry.vertexData.size();
}
return SortingMeshData {{std::move(newEntry)}};
}
return sortingMesh;
}

View File

@ -79,6 +79,10 @@ ChunksRenderer::ChunksRenderer(
*level->content, cache, settings
);
logger.info() << "created " << threadPool.getWorkersCount() << " workers";
const vattr attrs[]{ {3}, {2}, {1}, {0} };
float buf[]{};
sortedMesh = std::make_unique<Mesh>(buf, 0, attrs);
}
ChunksRenderer::~ChunksRenderer() {
@ -210,16 +214,19 @@ void ChunksRenderer::drawChunks(
}
void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
const vattr attrs[]{ {3}, {2}, {1}, {0} };
timeutil::ScopeLogTimer log(444);
std::vector<const SortingMeshEntry*> entries;
const auto& chunks = level.chunks->getChunks();
auto pposition = camera.position;
size_t size = 0;
bool culling = settings.graphics.frustumCulling.get();
for (size_t i = 0; i < indices.size(); i++) {
auto chunk = level.chunks->getChunks()[indices[i].index];
for (const auto& index : indices) {
const auto& chunk = chunks[index.index];
if (chunk == nullptr || !chunk->flags.lighted) {
continue;
}
@ -238,19 +245,22 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
if (!frustum.isBoxVisible(min, max)) continue;
auto& chunkEntries = found->second.sortingMesh.entries;
for (auto& entry : chunkEntries) {
entry.distance = glm::distance2(entry.position, pposition);
entry.distance = static_cast<long long>(glm::distance2(entry.position, pposition));
}
std::sort(chunkEntries.begin(), chunkEntries.end());
for (const auto& entry : chunkEntries) {
size += entry.vertexData.size();
entries.push_back(&entry);
}
}
std::sort(entries.begin(), entries.end(), [=](const auto& a, const auto& b) {
return *a < *b;
});
util::Buffer<float> buffer(size);
static util::Buffer<float> buffer;
if (buffer.size() < size) {
buffer = util::Buffer<float>(size);
}
size_t offset = 0;
for (const auto& entry : entries) {
std::memcpy(
@ -260,8 +270,8 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
);
offset += entry->vertexData.size();
}
Mesh mesh(buffer.data(), size / 6, attrs);
sortedMesh->reload(buffer.data(), size / 6);
shader.uniformMatrix("u_model", glm::mat4(1.0f));
mesh.draw();
sortedMesh->draw();
}

View File

@ -54,6 +54,7 @@ class ChunksRenderer {
bool drawChunk(
size_t index, const Camera& camera, Shader& shader, bool culling
);
std::unique_ptr<Mesh> sortedMesh;
public:
ChunksRenderer(
const Level* level,

View File

@ -12,7 +12,7 @@ class Mesh;
struct SortingMeshEntry {
glm::vec3 position;
util::Buffer<float> vertexData;
float distance;
long long distance;
inline bool operator<(const SortingMeshEntry& o) const noexcept {
return distance > o.distance;