update ModelBatch semantics
This commit is contained in:
parent
ea0add3017
commit
94fe5eeb5b
@ -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;
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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,31 +59,44 @@ 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();
|
flush();
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < mesh.vertices.size() / 3; i++) {
|
for (size_t j = 0; j < 3; j++) {
|
||||||
if (index + VERTEX_SIZE * 3 > capacity) {
|
const auto& vert = vertexData[i * 3 + j];
|
||||||
flush();
|
auto norm = rotation * vert.normal;
|
||||||
}
|
float d = glm::dot(norm, SUN_VECTOR);
|
||||||
for (size_t j = 0; j < 3; j++) {
|
d = 0.8f + d * 0.2f;
|
||||||
const auto& vert = mesh.vertices[i * 3 + j];
|
|
||||||
auto norm = rotation * vert.normal;
|
auto color = lights * d;
|
||||||
float d = glm::dot(norm, SUN_VECTOR);
|
vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, color);
|
||||||
d = 0.8f + d * 0.2f;
|
|
||||||
|
|
||||||
auto color = lights * d;
|
|
||||||
vertex(vert.coord, vert.uv, color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
flush();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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) {
|
||||||
if (index + 36 < capacity*VERTEX_SIZE) {
|
if (index + 36 < capacity*VERTEX_SIZE) {
|
||||||
flush();
|
flush();
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user