50 lines
1.5 KiB
C++
50 lines
1.5 KiB
C++
#pragma once
|
|
#include "hd2d/GL.h"
|
|
#include "hd2d/Texture.h"
|
|
|
|
#include <glm/glm.hpp>
|
|
#include <vector>
|
|
|
|
namespace hd2d {
|
|
|
|
// One upright pixel-art sprite. `pos` is where the lowest opaque pixel row
|
|
// touches the ground; sprites always face the camera around the Y axis.
|
|
struct BillboardInstance {
|
|
glm::vec3 pos{0.0f};
|
|
float sway = 0.0f; // wind / player-push response (0 = rigid)
|
|
glm::vec2 size{1.0f}; // world units of the full texture quad
|
|
float flip = 0.0f; // 1 = mirror horizontally
|
|
float tint = 1.0f; // brightness multiplier (breaks up repetition)
|
|
};
|
|
|
|
// Instanced batch of billboards sharing one texture.
|
|
class BillboardBatch {
|
|
public:
|
|
BillboardBatch() = default;
|
|
BillboardBatch(const BillboardBatch&) = delete;
|
|
BillboardBatch& operator=(const BillboardBatch&) = delete;
|
|
~BillboardBatch();
|
|
|
|
bool loadTexture(const std::string& path) { return texture.load(path); }
|
|
void upload(); // call after editing `instances`
|
|
void draw() const;
|
|
|
|
// World size that keeps the texture at `pixelsPerUnit` texel density.
|
|
glm::vec2 sizeForDensity(float pixelsPerUnit) const {
|
|
return glm::vec2(texture.size()) / pixelsPerUnit;
|
|
}
|
|
|
|
Texture texture;
|
|
std::vector<BillboardInstance> instances;
|
|
bool castShadows = true;
|
|
bool inReflections = true;
|
|
float emissive = 0.0f; // unlit contribution, for glowing sprites
|
|
|
|
private:
|
|
GLuint vao_ = 0, vbo_ = 0;
|
|
size_t capacity_ = 0;
|
|
GLsizei count_ = 0;
|
|
};
|
|
|
|
} // namespace hd2d
|