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); glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
if (vertexBuffer != nullptr && vertices != 0) { if (vertexBuffer != nullptr && vertices != 0) {
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * vertices, vertexBuffer, GL_STREAM_DRAW);
} } else {
else { glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STREAM_DRAW);
glBufferData(GL_ARRAY_BUFFER, 0, {}, GL_STATIC_DRAW);
} }
if (indexBuffer != nullptr && indices != 0) { if (indexBuffer != nullptr && indices != 0) {
if (ibo == 0) glGenBuffers(1, &ibo); if (ibo == 0) glGenBuffers(1, &ibo);

View File

@ -498,6 +498,9 @@ SortingMeshData BlocksRenderer::renderTranslucent(
) { ) {
SortingMeshData sortingMesh {{}}; SortingMeshData sortingMesh {{}};
AABB aabb {};
bool aabbInit = false;
size_t totalSize = 0;
for (const auto drawGroup : *content.drawGroups) { for (const auto drawGroup : *content.drawGroups) {
int begin = beginEnds[drawGroup][0]; int begin = beginEnds[drawGroup][0];
if (begin == 0) { if (begin == 0) {
@ -557,21 +560,51 @@ SortingMeshData BlocksRenderer::renderTranslucent(
), ),
util::Buffer<float>(indexSize * VERTEX_SIZE)}; util::Buffer<float>(indexSize * VERTEX_SIZE)};
totalSize += entry.vertexData.size();
for (int j = 0; j < indexSize; j++) { for (int j = 0; j < indexSize; j++) {
std::memcpy( std::memcpy(
entry.vertexData.data() + j * VERTEX_SIZE, entry.vertexData.data() + j * VERTEX_SIZE,
vertexBuffer.get() + indexBuffer[j] * VERTEX_SIZE, vertexBuffer.get() + indexBuffer[j] * VERTEX_SIZE,
sizeof(float) * VERTEX_SIZE sizeof(float) * VERTEX_SIZE
); );
entry.vertexData[j * VERTEX_SIZE + 0] += chunk->x * CHUNK_W + 0.5f; float& vx = entry.vertexData[j * VERTEX_SIZE + 0];
entry.vertexData[j * VERTEX_SIZE + 1] += 0.5f; float& vy = entry.vertexData[j * VERTEX_SIZE + 1];
entry.vertexData[j * VERTEX_SIZE + 2] += chunk->z * CHUNK_D + 0.5f; 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)); sortingMesh.entries.push_back(std::move(entry));
vertexOffset = 0; vertexOffset = 0;
indexOffset = indexSize = 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; return sortingMesh;
} }

View File

@ -79,6 +79,10 @@ ChunksRenderer::ChunksRenderer(
*level->content, cache, settings *level->content, cache, settings
); );
logger.info() << "created " << threadPool.getWorkersCount() << " workers"; 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() { ChunksRenderer::~ChunksRenderer() {
@ -210,16 +214,19 @@ void ChunksRenderer::drawChunks(
} }
void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
const vattr attrs[]{ {3}, {2}, {1}, {0} }; timeutil::ScopeLogTimer log(444);
std::vector<const SortingMeshEntry*> entries; std::vector<const SortingMeshEntry*> entries;
const auto& chunks = level.chunks->getChunks();
auto pposition = camera.position; auto pposition = camera.position;
size_t size = 0; size_t size = 0;
bool culling = settings.graphics.frustumCulling.get(); 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) { if (chunk == nullptr || !chunk->flags.lighted) {
continue; continue;
} }
@ -238,19 +245,22 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
if (!frustum.isBoxVisible(min, max)) continue; if (!frustum.isBoxVisible(min, max)) continue;
auto& chunkEntries = found->second.sortingMesh.entries; auto& chunkEntries = found->second.sortingMesh.entries;
for (auto& entry : chunkEntries) { 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) { for (const auto& entry : chunkEntries) {
size += entry.vertexData.size(); size += entry.vertexData.size();
entries.push_back(&entry); 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; size_t offset = 0;
for (const auto& entry : entries) { for (const auto& entry : entries) {
std::memcpy( std::memcpy(
@ -260,8 +270,8 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
); );
offset += entry->vertexData.size(); 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)); shader.uniformMatrix("u_model", glm::mat4(1.0f));
mesh.draw(); sortedMesh->draw();
} }

View File

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

View File

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