optimize (part 1)
This commit is contained in:
parent
4400366719
commit
b28bcf052b
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user