| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- #pragma once
- #include "draw_queue.h"
- #include "gl/primitives.h"
- #include "primitive_batch.h"
- #include <QMatrix4x4>
- #include <QVector3D>
- namespace Render::GL {
- class Mesh;
- class Texture;
- } // namespace Render::GL
- namespace Render::GL {
- class ISubmitter {
- public:
- virtual ~ISubmitter() = default;
- virtual void mesh(Mesh *mesh, const QMatrix4x4 &model, const QVector3D &color,
- Texture *tex = nullptr, float alpha = 1.0F,
- int material_id = 0) = 0;
- virtual void cylinder(const QVector3D &start, const QVector3D &end,
- float radius, const QVector3D &color,
- float alpha = 1.0F) = 0;
- virtual void selection_ring(const QMatrix4x4 &model, float alpha_inner,
- float alpha_outer, const QVector3D &color) = 0;
- virtual void grid(const QMatrix4x4 &model, const QVector3D &color,
- float cell_size, float thickness, float extent) = 0;
- virtual void selection_smoke(const QMatrix4x4 &model, const QVector3D &color,
- float base_alpha = 0.15F) = 0;
- virtual void healing_beam(const QVector3D &start, const QVector3D &end,
- const QVector3D &color, float progress,
- float beam_width, float intensity, float time) = 0;
- virtual void healer_aura(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) = 0;
- virtual void combat_dust(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) = 0;
- virtual void stone_impact(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) = 0;
- virtual void mode_indicator(const QMatrix4x4 &model, int mode_type,
- const QVector3D &color, float alpha = 1.0F) = 0;
- };
- namespace detail {
- inline auto decompose_unit_cylinder(const QMatrix4x4 &model, QVector3D &start,
- QVector3D &end, float &radius) -> bool {
- start = model.map(QVector3D(0.0F, -0.5F, 0.0F));
- end = model.map(QVector3D(0.0F, 0.5F, 0.0F));
- QVector3D const sx = model.mapVector(QVector3D(1.0F, 0.0F, 0.0F));
- QVector3D const sz = model.mapVector(QVector3D(0.0F, 0.0F, 1.0F));
- radius = 0.5F * (sx.length() + sz.length());
- return radius > 0.0F;
- }
- } // namespace detail
- class QueueSubmitter : public ISubmitter {
- public:
- explicit QueueSubmitter(DrawQueue *queue) : m_queue(queue) {}
- [[nodiscard]] Shader *shader() const { return m_shader; }
- void set_shader(Shader *shader) { m_shader = shader; }
- void mesh(Mesh *mesh, const QMatrix4x4 &model, const QVector3D &color,
- Texture *tex = nullptr, float alpha = 1.0F,
- int material_id = 0) override {
- if ((m_queue == nullptr) || (mesh == nullptr)) {
- return;
- }
- if (mesh == get_unit_cylinder() && (tex == nullptr) &&
- (m_shader == nullptr)) {
- QVector3D start;
- QVector3D end;
- float radius = 0.0F;
- if (detail::decompose_unit_cylinder(model, start, end, radius)) {
- CylinderCmd cyl;
- cyl.start = start;
- cyl.end = end;
- cyl.radius = radius;
- cyl.color = color;
- cyl.alpha = alpha;
- m_queue->submit(cyl);
- return;
- }
- }
- MeshCmd cmd;
- cmd.mesh = mesh;
- cmd.texture = tex;
- cmd.model = model;
- cmd.color = color;
- cmd.alpha = alpha;
- cmd.material_id = material_id;
- cmd.shader = m_shader;
- m_queue->submit(cmd);
- }
- void cylinder(const QVector3D &start, const QVector3D &end, float radius,
- const QVector3D &color, float alpha = 1.0F) override {
- if (m_queue == nullptr) {
- return;
- }
- CylinderCmd cmd;
- cmd.start = start;
- cmd.end = end;
- cmd.radius = radius;
- cmd.color = color;
- cmd.alpha = alpha;
- m_queue->submit(cmd);
- }
- void selection_ring(const QMatrix4x4 &model, float alpha_inner,
- float alpha_outer, const QVector3D &color) override {
- if (m_queue == nullptr) {
- return;
- }
- SelectionRingCmd cmd;
- cmd.model = model;
- cmd.alpha_inner = alpha_inner;
- cmd.alpha_outer = alpha_outer;
- cmd.color = color;
- m_queue->submit(cmd);
- }
- void grid(const QMatrix4x4 &model, const QVector3D &color, float cell_size,
- float thickness, float extent) override {
- if (m_queue == nullptr) {
- return;
- }
- GridCmd cmd;
- cmd.model = model;
- cmd.color = color;
- cmd.cell_size = cell_size;
- cmd.thickness = thickness;
- cmd.extent = extent;
- m_queue->submit(cmd);
- }
- void selection_smoke(const QMatrix4x4 &model, const QVector3D &color,
- float base_alpha = 0.15F) override {
- if (m_queue == nullptr) {
- return;
- }
- SelectionSmokeCmd cmd;
- cmd.model = model;
- cmd.color = color;
- cmd.base_alpha = base_alpha;
- m_queue->submit(cmd);
- }
- void healing_beam(const QVector3D &start, const QVector3D &end,
- const QVector3D &color, float progress, float beam_width,
- float intensity, float time) override {
- if (m_queue == nullptr) {
- return;
- }
- HealingBeamCmd cmd;
- cmd.start_pos = start;
- cmd.end_pos = end;
- cmd.color = color;
- cmd.progress = progress;
- cmd.beam_width = beam_width;
- cmd.intensity = intensity;
- cmd.time = time;
- m_queue->submit(cmd);
- }
- void healer_aura(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_queue == nullptr) {
- return;
- }
- HealerAuraCmd cmd;
- cmd.position = position;
- cmd.color = color;
- cmd.radius = radius;
- cmd.intensity = intensity;
- cmd.time = time;
- m_queue->submit(cmd);
- }
- void combat_dust(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_queue == nullptr) {
- return;
- }
- CombatDustCmd cmd;
- cmd.position = position;
- cmd.color = color;
- cmd.radius = radius;
- cmd.intensity = intensity;
- cmd.time = time;
- m_queue->submit(cmd);
- }
- void stone_impact(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_queue == nullptr) {
- return;
- }
- StoneImpactCmd cmd;
- cmd.position = position;
- cmd.color = color;
- cmd.radius = radius;
- cmd.intensity = intensity;
- cmd.time = time;
- m_queue->submit(cmd);
- }
- void mode_indicator(const QMatrix4x4 &model, int mode_type,
- const QVector3D &color, float alpha = 1.0F) override {
- if (m_queue == nullptr) {
- return;
- }
- ModeIndicatorCmd cmd;
- cmd.model = model;
- cmd.mode_type = mode_type;
- cmd.color = color;
- cmd.alpha = alpha;
- m_queue->submit(cmd);
- }
- private:
- DrawQueue *m_queue = nullptr;
- Shader *m_shader = nullptr;
- };
- class BatchingSubmitter : public ISubmitter {
- public:
- explicit BatchingSubmitter(ISubmitter *fallback,
- PrimitiveBatcher *batcher = nullptr)
- : m_fallback(fallback), m_batcher(batcher) {}
- [[nodiscard]] ISubmitter *fallback_submitter() const { return m_fallback; }
- void set_batcher(PrimitiveBatcher *batcher) { m_batcher = batcher; }
- void set_enabled(bool enabled) { m_enabled = enabled; }
- void mesh(Mesh *mesh, const QMatrix4x4 &model, const QVector3D &color,
- Texture *tex = nullptr, float alpha = 1.0F,
- int material_id = 0) override {
- if (m_enabled && m_batcher != nullptr && tex == nullptr) {
- if (mesh == get_unit_sphere()) {
- m_batcher->add_sphere(model, color, alpha);
- return;
- }
- if (mesh == get_unit_cylinder()) {
- m_batcher->add_cylinder(model, color, alpha);
- return;
- }
- if (mesh == get_unit_cone()) {
- m_batcher->add_cone(model, color, alpha);
- return;
- }
- }
- if (m_fallback != nullptr) {
- m_fallback->mesh(mesh, model, color, tex, alpha, material_id);
- }
- }
- void cylinder(const QVector3D &start, const QVector3D &end, float radius,
- const QVector3D &color, float alpha = 1.0F) override {
- if (m_fallback != nullptr) {
- m_fallback->cylinder(start, end, radius, color, alpha);
- }
- }
- void selection_ring(const QMatrix4x4 &model, float alpha_inner,
- float alpha_outer, const QVector3D &color) override {
- if (m_fallback != nullptr) {
- m_fallback->selection_ring(model, alpha_inner, alpha_outer, color);
- }
- }
- void grid(const QMatrix4x4 &model, const QVector3D &color, float cell_size,
- float thickness, float extent) override {
- if (m_fallback != nullptr) {
- m_fallback->grid(model, color, cell_size, thickness, extent);
- }
- }
- void selection_smoke(const QMatrix4x4 &model, const QVector3D &color,
- float base_alpha = 0.15F) override {
- if (m_fallback != nullptr) {
- m_fallback->selection_smoke(model, color, base_alpha);
- }
- }
- void healing_beam(const QVector3D &start, const QVector3D &end,
- const QVector3D &color, float progress, float beam_width,
- float intensity, float time) override {
- if (m_fallback != nullptr) {
- m_fallback->healing_beam(start, end, color, progress, beam_width,
- intensity, time);
- }
- }
- void healer_aura(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_fallback != nullptr) {
- m_fallback->healer_aura(position, color, radius, intensity, time);
- }
- }
- void combat_dust(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_fallback != nullptr) {
- m_fallback->combat_dust(position, color, radius, intensity, time);
- }
- }
- void stone_impact(const QVector3D &position, const QVector3D &color,
- float radius, float intensity, float time) override {
- if (m_fallback != nullptr) {
- m_fallback->stone_impact(position, color, radius, intensity, time);
- }
- }
- void mode_indicator(const QMatrix4x4 &model, int mode_type,
- const QVector3D &color, float alpha = 1.0F) override {
- if (m_fallback != nullptr) {
- m_fallback->mode_indicator(model, mode_type, color, alpha);
- }
- }
- private:
- ISubmitter *m_fallback = nullptr;
- PrimitiveBatcher *m_batcher = nullptr;
- bool m_enabled = true;
- };
- } // namespace Render::GL
|