update ModelBatch semantics

This commit is contained in:
MihailRis 2024-06-23 01:57:28 +03:00
parent ea0add3017
commit 94fe5eeb5b
7 changed files with 97 additions and 35 deletions

View File

@ -122,9 +122,9 @@ assetload::postfunc assetload::font(
) { ) {
auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>(); auto pages = std::make_shared<std::vector<std::unique_ptr<ImageData>>>();
for (size_t i = 0; i <= 4; i++) { for (size_t i = 0; i <= 4; i++) {
std::string name = filename + "_" + std::to_string(i) + ".png"; std::string pagefile = filename + "_" + std::to_string(i) + ".png";
name = paths->find(name).string(); pagefile = paths->find(pagefile).string();
pages->push_back(imageio::read(name)); pages->push_back(imageio::read(pagefile));
} }
return [=](auto assets) { return [=](auto assets) {
int res = pages->at(0)->getHeight() / 16; int res = pages->at(0)->getHeight() / 16;

View File

@ -62,6 +62,11 @@ std::shared_ptr<UINode> create_debug_panel(
panel->add(create_label([](){ panel->add(create_label([](){
return L"meshes: " + std::to_wstring(Mesh::meshesCount); return L"meshes: " + std::to_wstring(Mesh::meshesCount);
})); }));
panel->add(create_label([](){
int drawCalls = Mesh::drawCalls;
Mesh::drawCalls = 0;
return L"draw-calls: " + std::to_wstring(drawCalls);
}));
panel->add(create_label([](){ panel->add(create_label([](){
return L"speakers: " + std::to_wstring(audio::count_speakers())+ return L"speakers: " + std::to_wstring(audio::count_speakers())+
L" streams: " + std::to_wstring(audio::count_streams()); L" streams: " + std::to_wstring(audio::count_streams());

View File

@ -2,6 +2,7 @@
#include <GL/glew.h> #include <GL/glew.h>
int Mesh::meshesCount = 0; int Mesh::meshesCount = 0;
int Mesh::drawCalls = 0;
Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) : Mesh::Mesh(const float* vertexBuffer, size_t vertices, const int* indexBuffer, size_t indices, const vattr* attrs) :
ibo(0), ibo(0),
@ -60,6 +61,7 @@ void Mesh::reload(const float* vertexBuffer, size_t vertices, const int* indexBu
} }
void Mesh::draw(unsigned int primitive){ void Mesh::draw(unsigned int primitive){
drawCalls++;
glBindVertexArray(vao); glBindVertexArray(vao);
if (ibo != 0) { if (ibo != 0) {
glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0); glDrawElements(primitive, indices, GL_UNSIGNED_INT, 0);

View File

@ -37,6 +37,7 @@ public:
/// @brief Total numbers of alive mesh objects /// @brief Total numbers of alive mesh objects
static int meshesCount; static int meshesCount;
static int drawCalls;
}; };
#endif // GRAPHICS_CORE_MESH_HPP_ #endif // GRAPHICS_CORE_MESH_HPP_

View File

@ -50,8 +50,8 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks)
ModelBatch::~ModelBatch() { ModelBatch::~ModelBatch() {
} }
void ModelBatch::draw(const model::Model* model) { void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation) {
glm::vec3 gpos = combined * glm::vec4(glm::vec3(), 1.0f); glm::vec3 gpos = matrix * glm::vec4(glm::vec3(), 1.0f);
light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z); light_t light = chunks->getLight(gpos.x, gpos.y, gpos.z);
glm::vec4 lights ( glm::vec4 lights (
Lightmap::extract(light, 0) / 15.0f, Lightmap::extract(light, 0) / 15.0f,
@ -59,29 +59,42 @@ void ModelBatch::draw(const model::Model* model) {
Lightmap::extract(light, 2) / 15.0f, Lightmap::extract(light, 2) / 15.0f,
Lightmap::extract(light, 3) / 15.0f Lightmap::extract(light, 3) / 15.0f
); );
for (const auto& mesh : model->meshes) { setTexture(assets->get<Texture>(mesh.texture));
auto texture = assets->get<Texture>(mesh.texture); size_t vcount = mesh.vertices.size();
if (texture) { const auto& vertexData = mesh.vertices.data();
texture->bind(); for (size_t i = 0; i < vcount / 3; i++) {
} else { if (index + VERTEX_SIZE * 3 > capacity * VERTEX_SIZE) {
blank->bind();
}
for (size_t i = 0; i < mesh.vertices.size() / 3; i++) {
if (index + VERTEX_SIZE * 3 > capacity) {
flush(); flush();
} }
for (size_t j = 0; j < 3; j++) { for (size_t j = 0; j < 3; j++) {
const auto& vert = mesh.vertices[i * 3 + j]; const auto& vert = vertexData[i * 3 + j];
auto norm = rotation * vert.normal; auto norm = rotation * vert.normal;
float d = glm::dot(norm, SUN_VECTOR); float d = glm::dot(norm, SUN_VECTOR);
d = 0.8f + d * 0.2f; d = 0.8f + d * 0.2f;
auto color = lights * d; auto color = lights * d;
vertex(vert.coord, vert.uv, color); vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, color);
} }
} }
}
void ModelBatch::draw(const model::Model* model) {
for (const auto& mesh : model->meshes) {
entries.push_back({combined, rotation, &mesh});
}
}
void ModelBatch::render() {
std::sort(entries.begin(), entries.end(),
[](const DrawEntry& a, const DrawEntry& b) {
return a.mesh->texture < b.mesh->texture;
}
);
for (auto& entry : entries) {
draw(*entry.mesh, entry.matrix, entry.rotation);
}
flush(); flush();
} entries.clear();
} }
void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) { void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) {
@ -98,11 +111,24 @@ void ModelBatch::box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights) {
plane(pos-X*size, Z*size, Y*size, -X, lights); plane(pos-X*size, Z*size, Y*size, -X, lights);
} }
void ModelBatch::setTexture(Texture* texture) {
if (texture == nullptr) {
texture = blank.get();
}
if (texture != this->texture) {
flush();
}
this->texture = texture;
}
void ModelBatch::flush() { void ModelBatch::flush() {
if (index == 0) { if (index == 0) {
return; return;
} }
// blank->bind(); if (texture == nullptr) {
texture = blank.get();
}
texture->bind();
mesh->reload(buffer.get(), index / VERTEX_SIZE); mesh->reload(buffer.get(), index / VERTEX_SIZE);
mesh->draw(); mesh->draw();
index = 0; index = 0;

View File

@ -11,12 +11,13 @@ class Chunks;
class Assets; class Assets;
namespace model { namespace model {
struct Mesh;
struct Model; struct Model;
} }
class ModelBatch { class ModelBatch {
std::unique_ptr<float[]> buffer; std::unique_ptr<float[]> const buffer;
size_t capacity; size_t const capacity;
size_t index; size_t index;
std::unique_ptr<Mesh> mesh; std::unique_ptr<Mesh> mesh;
@ -28,6 +29,7 @@ class ModelBatch {
Assets* assets; Assets* assets;
Chunks* chunks; Chunks* chunks;
Texture* texture = nullptr;
static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f}; static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f};
@ -35,7 +37,6 @@ class ModelBatch {
glm::vec3 pos, glm::vec2 uv, glm::vec4 light glm::vec3 pos, glm::vec2 uv, glm::vec4 light
) { ) {
float* buffer = this->buffer.get(); float* buffer = this->buffer.get();
pos = combined * glm::vec4(pos, 1.0f);
buffer[index++] = pos.x; buffer[index++] = pos.x;
buffer[index++] = pos.y; buffer[index++] = pos.y;
buffer[index++] = pos.z; buffer[index++] = pos.z;
@ -70,6 +71,18 @@ class ModelBatch {
vertex(pos+right+up, {1,1}, color); vertex(pos+right+up, {1,1}, color);
vertex(pos-right+up, {0,1}, color); vertex(pos-right+up, {0,1}, color);
} }
void draw(const model::Mesh& mesh, const glm::mat4& matrix, const glm::mat3& rotation);
void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights);
void setTexture(Texture* texture);
void flush();
struct DrawEntry {
glm::mat4 matrix;
glm::mat3 rotation;
const model::Mesh* mesh;
};
std::vector<DrawEntry> entries;
public: public:
ModelBatch(size_t capacity, Assets* assets, Chunks* chunks); ModelBatch(size_t capacity, Assets* assets, Chunks* chunks);
~ModelBatch(); ~ModelBatch();
@ -80,12 +93,9 @@ public:
void pushMatrix(glm::mat4 matrix); void pushMatrix(glm::mat4 matrix);
void popMatrix(); void popMatrix();
void box(glm::vec3 pos, glm::vec3 size, glm::vec4 lights);
void draw(const model::Model* model); void draw(const model::Model* model);
void flush(); void render();
}; };
#endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_ #endif // GRAPHICS_RENDER_MODEL_BATCH_HPP_

View File

@ -50,7 +50,7 @@ WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* pl
player(player), player(player),
frustumCulling(std::make_unique<Frustum>()), frustumCulling(std::make_unique<Frustum>()),
lineBatch(std::make_unique<LineBatch>()), lineBatch(std::make_unique<LineBatch>()),
modelBatch(std::make_unique<ModelBatch>(1000, engine->getAssets(), level->chunks.get())) modelBatch(std::make_unique<ModelBatch>(20'000, engine->getAssets(), level->chunks.get()))
{ {
renderer = std::make_unique<ChunksRenderer>( renderer = std::make_unique<ChunksRenderer>(
level, level,
@ -195,7 +195,25 @@ void WorldRenderer::renderLevel(
drawChunks(level->chunks.get(), camera, shader); drawChunks(level->chunks.get(), camera, shader);
shader->uniformMatrix("u_model", glm::mat4(1.0f)); shader->uniformMatrix("u_model", glm::mat4(1.0f));
/// draw models here if (auto model = assets->get<model::Model>("cube")) {
srand(0);
float timer = Window::time();
for (size_t i = 0; i < 10000; i++) {
float x = (rand() % 5000)*0.1f;
float y = (rand() % 1000)*0.1f + 60;
float z = (rand() % 5000)*0.1f;
glm::vec3 coord(x, y, z);
int rot = rand() % 1000;
if (frustumCulling->IsBoxVisible(coord, coord)) {
modelBatch->translate(coord);
modelBatch->rotate(glm::vec3(0, 1, 0), timer*3+rot);
modelBatch->draw(model);
modelBatch->popMatrix();
modelBatch->popMatrix();
}
}
}
modelBatch->render();
skybox->unbind(); skybox->unbind();
} }