add MainBatch & refactor ModelBatch, Batch3D
This commit is contained in:
@@ -118,12 +118,12 @@ void Batch3D::texture(const Texture* new_texture){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::sprite(
|
void Batch3D::sprite(
|
||||||
glm::vec3 pos,
|
const glm::vec3& pos,
|
||||||
glm::vec3 up,
|
const glm::vec3& up,
|
||||||
glm::vec3 right,
|
const glm::vec3& right,
|
||||||
float w, float h,
|
float w, float h,
|
||||||
const UVRegion& uv,
|
const UVRegion& uv,
|
||||||
glm::vec4 color
|
const glm::vec4& color
|
||||||
){
|
){
|
||||||
const float r = color.r;
|
const float r = color.r;
|
||||||
const float g = color.g;
|
const float g = color.g;
|
||||||
@@ -175,7 +175,7 @@ inline glm::vec4 do_tint(float value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::xSprite(
|
void Batch3D::xSprite(
|
||||||
float w, float h, const UVRegion& uv, const glm::vec4 tint, bool shading
|
float w, float h, const UVRegion& uv, const glm::vec4& tint, bool shading
|
||||||
) {
|
) {
|
||||||
face(
|
face(
|
||||||
glm::vec3(-w * 0.25f, 0.0f, -w * 0.25f),
|
glm::vec3(-w * 0.25f, 0.0f, -w * 0.25f),
|
||||||
@@ -194,10 +194,10 @@ void Batch3D::xSprite(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::cube(
|
void Batch3D::cube(
|
||||||
const glm::vec3 coord,
|
const glm::vec3& coord,
|
||||||
const glm::vec3 size,
|
const glm::vec3& size,
|
||||||
const UVRegion(&texfaces)[6],
|
const UVRegion(&texfaces)[6],
|
||||||
const glm::vec4 tint,
|
const glm::vec4& tint,
|
||||||
bool shading
|
bool shading
|
||||||
) {
|
) {
|
||||||
const glm::vec3 X(1.0f, 0.0f, 0.0f);
|
const glm::vec3 X(1.0f, 0.0f, 0.0f);
|
||||||
@@ -237,22 +237,24 @@ void Batch3D::cube(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::blockCube(
|
void Batch3D::blockCube(
|
||||||
const glm::vec3 size,
|
const glm::vec3& size,
|
||||||
const UVRegion(&texfaces)[6],
|
const UVRegion(&texfaces)[6],
|
||||||
const glm::vec4 tint,
|
const glm::vec4& tint,
|
||||||
bool shading
|
bool shading
|
||||||
) {
|
) {
|
||||||
cube((1.0f - size) * -0.5f, size, texfaces, tint, shading);
|
cube((1.0f - size) * -0.5f, size, texfaces, tint, shading);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::vertex(glm::vec3 coord, glm::vec2 uv, glm::vec4 tint) {
|
void Batch3D::vertex(
|
||||||
|
const glm::vec3& coord, const glm::vec2& uv, const glm::vec4& tint
|
||||||
|
) {
|
||||||
if (index + B3D_VERTEX_SIZE >= capacity) {
|
if (index + B3D_VERTEX_SIZE >= capacity) {
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
vertex(coord, uv, tint.r, tint.g, tint.b, tint.a);
|
vertex(coord, uv, tint.r, tint.g, tint.b, tint.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::point(glm::vec3 coord, glm::vec4 tint) {
|
void Batch3D::point(const glm::vec3& coord, const glm::vec4& tint) {
|
||||||
if (index + B3D_VERTEX_SIZE >= capacity) {
|
if (index + B3D_VERTEX_SIZE >= capacity) {
|
||||||
flushPoints();
|
flushPoints();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,36 +49,36 @@ public:
|
|||||||
void begin();
|
void begin();
|
||||||
void texture(const Texture* texture);
|
void texture(const Texture* texture);
|
||||||
void sprite(
|
void sprite(
|
||||||
glm::vec3 pos,
|
const glm::vec3& pos,
|
||||||
glm::vec3 up,
|
const glm::vec3& up,
|
||||||
glm::vec3 right,
|
const glm::vec3& right,
|
||||||
float w,
|
float w,
|
||||||
float h,
|
float h,
|
||||||
const UVRegion& uv,
|
const UVRegion& uv,
|
||||||
glm::vec4 tint
|
const glm::vec4& tint
|
||||||
);
|
);
|
||||||
void xSprite(
|
void xSprite(
|
||||||
float w,
|
float w,
|
||||||
float h,
|
float h,
|
||||||
const UVRegion& uv,
|
const UVRegion& uv,
|
||||||
const glm::vec4 tint,
|
const glm::vec4& tint,
|
||||||
bool shading = true
|
bool shading = true
|
||||||
);
|
);
|
||||||
void cube(
|
void cube(
|
||||||
const glm::vec3 coords,
|
const glm::vec3& coords,
|
||||||
const glm::vec3 size,
|
const glm::vec3& size,
|
||||||
const UVRegion (&texfaces)[6],
|
const UVRegion (&texfaces)[6],
|
||||||
const glm::vec4 tint,
|
const glm::vec4& tint,
|
||||||
bool shading = true
|
bool shading = true
|
||||||
);
|
);
|
||||||
void blockCube(
|
void blockCube(
|
||||||
const glm::vec3 size,
|
const glm::vec3& size,
|
||||||
const UVRegion (&texfaces)[6],
|
const UVRegion (&texfaces)[6],
|
||||||
const glm::vec4 tint,
|
const glm::vec4& tint,
|
||||||
bool shading = true
|
bool shading = true
|
||||||
);
|
);
|
||||||
void vertex(glm::vec3 pos, glm::vec2 uv, glm::vec4 tint);
|
void vertex(const glm::vec3& pos, const glm::vec2& uv, const glm::vec4& tint);
|
||||||
void point(glm::vec3 pos, glm::vec4 tint);
|
void point(const glm::vec3& pos, const glm::vec4& tint);
|
||||||
void flush() override;
|
void flush() override;
|
||||||
void flushPoints();
|
void flushPoints();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "MainBatch.hpp"
|
||||||
|
|
||||||
|
#include "graphics/core/Texture.hpp"
|
||||||
|
#include "graphics/core/Mesh.hpp"
|
||||||
|
#include "graphics/core/ImageData.hpp"
|
||||||
|
|
||||||
|
#include "typedefs.hpp"
|
||||||
|
|
||||||
|
static const vattr attrs[] = {
|
||||||
|
{3}, {2}, {3}, {1}, {0}
|
||||||
|
};
|
||||||
|
|
||||||
|
MainBatch::MainBatch(size_t capacity)
|
||||||
|
: buffer(std::make_unique<float[]>(capacity * VERTEX_SIZE)),
|
||||||
|
capacity(capacity),
|
||||||
|
index(0),
|
||||||
|
mesh(std::make_unique<Mesh>(buffer.get(), 0, attrs)) {
|
||||||
|
|
||||||
|
const ubyte pixels[] = {
|
||||||
|
255, 255, 255, 255,
|
||||||
|
};
|
||||||
|
ImageData image(ImageFormat::rgba8888, 1, 1, pixels);
|
||||||
|
blank = Texture::from(&image);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainBatch::~MainBatch() = default;
|
||||||
|
|
||||||
|
void MainBatch::setTexture(const Texture* texture) {
|
||||||
|
if (texture == nullptr) {
|
||||||
|
texture = blank.get();
|
||||||
|
}
|
||||||
|
if (texture != this->texture) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
this->texture = texture;
|
||||||
|
region = UVRegion {0.0f, 0.0f, 1.0f, 1.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainBatch::setTexture(const Texture* texture, const UVRegion& region) {
|
||||||
|
setTexture(texture);
|
||||||
|
this->region = region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainBatch::flush() {
|
||||||
|
if (index == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (texture == nullptr) {
|
||||||
|
texture = blank.get();
|
||||||
|
}
|
||||||
|
texture->bind();
|
||||||
|
mesh->reload(buffer.get(), index / VERTEX_SIZE);
|
||||||
|
mesh->draw();
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainBatch::prepare(int vertices) {
|
||||||
|
if (index + VERTEX_SIZE * vertices > capacity * VERTEX_SIZE) {
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include "maths/UVRegion.hpp"
|
||||||
|
|
||||||
|
class Mesh;
|
||||||
|
class Texture;
|
||||||
|
|
||||||
|
class MainBatch {
|
||||||
|
std::unique_ptr<float[]> const buffer;
|
||||||
|
size_t const capacity;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
UVRegion region {0.0f, 0.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
|
std::unique_ptr<Mesh> mesh;
|
||||||
|
std::unique_ptr<Texture> blank;
|
||||||
|
|
||||||
|
const Texture* texture = nullptr;
|
||||||
|
public:
|
||||||
|
/// xyz, uv, color, compressed lights
|
||||||
|
static inline constexpr uint VERTEX_SIZE = 9;
|
||||||
|
|
||||||
|
MainBatch(size_t capacity);
|
||||||
|
|
||||||
|
~MainBatch();
|
||||||
|
|
||||||
|
void prepare(int vertices);
|
||||||
|
void setTexture(const Texture* texture);
|
||||||
|
void setTexture(const Texture* texture, const UVRegion& region);
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
inline void vertex(
|
||||||
|
glm::vec3 pos, glm::vec2 uv, glm::vec4 light, glm::vec3 tint
|
||||||
|
) {
|
||||||
|
float* buffer = this->buffer.get();
|
||||||
|
buffer[index++] = pos.x;
|
||||||
|
buffer[index++] = pos.y;
|
||||||
|
buffer[index++] = pos.z;
|
||||||
|
buffer[index++] = uv.x * region.getWidth() + region.u1;
|
||||||
|
buffer[index++] = uv.y * region.getHeight() + region.v1;
|
||||||
|
buffer[index++] = tint.x;
|
||||||
|
buffer[index++] = tint.y;
|
||||||
|
buffer[index++] = tint.z;
|
||||||
|
|
||||||
|
union {
|
||||||
|
float floating;
|
||||||
|
uint32_t integer;
|
||||||
|
} compressed;
|
||||||
|
|
||||||
|
compressed.integer = (static_cast<uint32_t>(light.r * 255) & 0xff) << 24;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.g * 255) & 0xff) << 16;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.b * 255) & 0xff) << 8;
|
||||||
|
compressed.integer |= (static_cast<uint32_t>(light.a * 255) & 0xff);
|
||||||
|
|
||||||
|
buffer[index++] = compressed.floating;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "lighting/Lightmap.hpp"
|
#include "lighting/Lightmap.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "MainBatch.hpp"
|
||||||
|
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/ext/matrix_transform.hpp>
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
@@ -18,13 +19,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
/// xyz, uv, color, compressed lights
|
|
||||||
inline constexpr uint VERTEX_SIZE = 9;
|
|
||||||
|
|
||||||
static const vattr attrs[] = {
|
|
||||||
{3}, {2}, {3}, {1}, {0}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline constexpr glm::vec3 X(1, 0, 0);
|
inline constexpr glm::vec3 X(1, 0, 0);
|
||||||
inline constexpr glm::vec3 Y(0, 1, 0);
|
inline constexpr glm::vec3 Y(0, 1, 0);
|
||||||
inline constexpr glm::vec3 Z(0, 0, 1);
|
inline constexpr glm::vec3 Z(0, 0, 1);
|
||||||
@@ -57,18 +51,10 @@ ModelBatch::ModelBatch(
|
|||||||
Chunks* chunks,
|
Chunks* chunks,
|
||||||
const EngineSettings* settings
|
const EngineSettings* settings
|
||||||
)
|
)
|
||||||
: buffer(std::make_unique<float[]>(capacity * VERTEX_SIZE)),
|
: batch(std::make_unique<MainBatch>(capacity)),
|
||||||
capacity(capacity),
|
|
||||||
index(0),
|
|
||||||
mesh(std::make_unique<Mesh>(buffer.get(), 0, attrs)),
|
|
||||||
assets(assets),
|
assets(assets),
|
||||||
chunks(chunks),
|
chunks(chunks),
|
||||||
settings(settings) {
|
settings(settings) {
|
||||||
const ubyte pixels[] = {
|
|
||||||
255, 255, 255, 255,
|
|
||||||
};
|
|
||||||
ImageData image(ImageFormat::rgba8888, 1, 1, pixels);
|
|
||||||
blank = Texture::from(&image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelBatch::~ModelBatch() = default;
|
ModelBatch::~ModelBatch() = default;
|
||||||
@@ -94,15 +80,13 @@ void ModelBatch::draw(const model::Mesh& mesh, const glm::mat4& matrix,
|
|||||||
size_t vcount = mesh.vertices.size();
|
size_t vcount = mesh.vertices.size();
|
||||||
const auto& vertexData = mesh.vertices.data();
|
const auto& vertexData = mesh.vertices.data();
|
||||||
for (size_t i = 0; i < vcount / 3; i++) {
|
for (size_t i = 0; i < vcount / 3; i++) {
|
||||||
if (index + VERTEX_SIZE * 3 > capacity * VERTEX_SIZE) {
|
batch->prepare(3);
|
||||||
flush();
|
|
||||||
}
|
|
||||||
for (size_t j = 0; j < 3; j++) {
|
for (size_t j = 0; j < 3; j++) {
|
||||||
const auto vert = vertexData[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;
|
||||||
vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, lights*d, tint);
|
batch->vertex(matrix * glm::vec4(vert.coord, 1.0f), vert.uv, lights*d, tint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +119,7 @@ void ModelBatch::render() {
|
|||||||
backlight
|
backlight
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
flush();
|
batch->flush();
|
||||||
entries.clear();
|
entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,37 +132,11 @@ void ModelBatch::setTexture(const std::string& name,
|
|||||||
if (varTextures && name.at(0) == '$') {
|
if (varTextures && name.at(0) == '$') {
|
||||||
const auto& found = varTextures->find(name);
|
const auto& found = varTextures->find(name);
|
||||||
if (found == varTextures->end()) {
|
if (found == varTextures->end()) {
|
||||||
return setTexture(nullptr);
|
return batch->setTexture(nullptr);
|
||||||
} else {
|
} else {
|
||||||
return setTexture(found->second, varTextures);
|
return setTexture(found->second, varTextures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto region = util::get_texture_region(*assets, name, "blocks:notfound");
|
||||||
auto textureRegion = util::get_texture_region(*assets, name, "blocks:notfound");
|
batch->setTexture(region.texture, region.region);
|
||||||
setTexture(textureRegion.texture);
|
|
||||||
region = textureRegion.region;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelBatch::setTexture(const Texture* texture) {
|
|
||||||
if (texture == nullptr) {
|
|
||||||
texture = blank.get();
|
|
||||||
}
|
|
||||||
if (texture != this->texture) {
|
|
||||||
flush();
|
|
||||||
}
|
|
||||||
this->texture = texture;
|
|
||||||
region = UVRegion {0.0f, 0.0f, 1.0f, 1.0f};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelBatch::flush() {
|
|
||||||
if (index == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (texture == nullptr) {
|
|
||||||
texture = blank.get();
|
|
||||||
}
|
|
||||||
texture->bind();
|
|
||||||
mesh->reload(buffer.get(), index / VERTEX_SIZE);
|
|
||||||
mesh->draw();
|
|
||||||
index = 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class Texture;
|
|||||||
class Chunks;
|
class Chunks;
|
||||||
class Assets;
|
class Assets;
|
||||||
struct EngineSettings;
|
struct EngineSettings;
|
||||||
|
class MainBatch;
|
||||||
|
|
||||||
namespace model {
|
namespace model {
|
||||||
struct Mesh;
|
struct Mesh;
|
||||||
@@ -22,47 +23,15 @@ namespace model {
|
|||||||
using texture_names_map = std::unordered_map<std::string, std::string>;
|
using texture_names_map = std::unordered_map<std::string, std::string>;
|
||||||
|
|
||||||
class ModelBatch {
|
class ModelBatch {
|
||||||
std::unique_ptr<float[]> const buffer;
|
|
||||||
size_t const capacity;
|
|
||||||
size_t index;
|
|
||||||
|
|
||||||
std::unique_ptr<Mesh> mesh;
|
|
||||||
std::unique_ptr<Texture> blank;
|
|
||||||
|
|
||||||
Assets* assets;
|
Assets* assets;
|
||||||
Chunks* chunks;
|
Chunks* chunks;
|
||||||
const Texture* texture = nullptr;
|
|
||||||
UVRegion region {0.0f, 0.0f, 1.0f, 1.0f};
|
|
||||||
const EngineSettings* settings;
|
const EngineSettings* settings;
|
||||||
glm::vec3 lightsOffset {};
|
glm::vec3 lightsOffset {};
|
||||||
|
|
||||||
static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f};
|
static inline glm::vec3 SUN_VECTOR {0.411934f, 0.863868f, -0.279161f};
|
||||||
|
|
||||||
inline void vertex(
|
std::unique_ptr<MainBatch> batch;
|
||||||
glm::vec3 pos, glm::vec2 uv, glm::vec4 light, glm::vec3 tint
|
|
||||||
) {
|
|
||||||
float* buffer = this->buffer.get();
|
|
||||||
buffer[index++] = pos.x;
|
|
||||||
buffer[index++] = pos.y;
|
|
||||||
buffer[index++] = pos.z;
|
|
||||||
buffer[index++] = uv.x * region.getWidth() + region.u1;
|
|
||||||
buffer[index++] = uv.y * region.getHeight() + region.v1;
|
|
||||||
buffer[index++] = tint.x;
|
|
||||||
buffer[index++] = tint.y;
|
|
||||||
buffer[index++] = tint.z;
|
|
||||||
|
|
||||||
union {
|
|
||||||
float floating;
|
|
||||||
uint32_t integer;
|
|
||||||
} compressed;
|
|
||||||
|
|
||||||
compressed.integer = (static_cast<uint32_t>(light.r * 255) & 0xff) << 24;
|
|
||||||
compressed.integer |= (static_cast<uint32_t>(light.g * 255) & 0xff) << 16;
|
|
||||||
compressed.integer |= (static_cast<uint32_t>(light.b * 255) & 0xff) << 8;
|
|
||||||
compressed.integer |= (static_cast<uint32_t>(light.a * 255) & 0xff);
|
|
||||||
|
|
||||||
buffer[index++] = compressed.floating;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(const model::Mesh& mesh,
|
void draw(const model::Mesh& mesh,
|
||||||
const glm::mat4& matrix,
|
const glm::mat4& matrix,
|
||||||
@@ -72,8 +41,6 @@ class ModelBatch {
|
|||||||
bool backlight);
|
bool backlight);
|
||||||
void setTexture(const std::string& name,
|
void setTexture(const std::string& name,
|
||||||
const texture_names_map* varTextures);
|
const texture_names_map* varTextures);
|
||||||
void setTexture(const Texture* texture);
|
|
||||||
void flush();
|
|
||||||
|
|
||||||
struct DrawEntry {
|
struct DrawEntry {
|
||||||
glm::mat4 matrix;
|
glm::mat4 matrix;
|
||||||
|
|||||||
Reference in New Issue
Block a user