Add debug minimap
This commit is contained in:
parent
0b82d1b428
commit
5029aad8f2
@ -92,6 +92,14 @@ void App::Frame()
|
||||
delta_time = 0.1f; // Cap delta time to avoid large jumps
|
||||
}
|
||||
|
||||
game::PlayerInputFlags new_input = input_ & ~prev_input_;
|
||||
prev_input_ = input_;
|
||||
|
||||
if (new_input & game::PI_DEBUG1)
|
||||
{
|
||||
renderer_.show_minimap = !renderer_.show_minimap;
|
||||
}
|
||||
|
||||
float aspect = static_cast<float>(viewport_size_.x) / static_cast<float>(viewport_size_.y);
|
||||
|
||||
renderer_.Begin(viewport_size_.x, viewport_size_.y);
|
||||
|
||||
@ -12,6 +12,7 @@ class App
|
||||
float time_ = 0.0f;
|
||||
glm::ivec2 viewport_size_ = { 800, 600 };
|
||||
game::PlayerInputFlags input_ = 0;
|
||||
game::PlayerInputFlags prev_input_ = 0;
|
||||
|
||||
float prev_time_ = 0.0f;
|
||||
|
||||
|
||||
@ -194,6 +194,96 @@ void game::Entity::UpdateLights()
|
||||
lights_valid_ = true;
|
||||
}
|
||||
|
||||
const gfx::VertexArray& game::Entity::GetDebugWireVA()
|
||||
{
|
||||
if (!debug_wire_va_)
|
||||
{
|
||||
CreateDebugWireVA();
|
||||
}
|
||||
|
||||
return *debug_wire_va_;
|
||||
}
|
||||
|
||||
void game::Entity::CreateDebugWireVA()
|
||||
{
|
||||
const int segments = 8;
|
||||
|
||||
struct CapsuleVertex
|
||||
{
|
||||
glm::vec3 pos;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
std::vector<CapsuleVertex> verts;
|
||||
std::vector<uint32_t> indices;
|
||||
|
||||
float half_height = capsule_.height * 0.5f;
|
||||
float radius = capsule_.radius;
|
||||
|
||||
const int num_half_circles = 8;
|
||||
const uint32_t color = 0xFFFFFFFF;
|
||||
|
||||
auto AddArc = [&](size_t axis, const glm::vec3 offset, size_t start, size_t end)
|
||||
{
|
||||
size_t num_verts = end - start + 1;
|
||||
|
||||
for (size_t i = 0; i < num_verts; ++i)
|
||||
{
|
||||
size_t p = start + i;
|
||||
float angle = p * glm::two_pi<float>() / segments;
|
||||
glm::vec2 circle = glm::vec2(glm::cos(angle), glm::sin(angle)) * radius;
|
||||
|
||||
if (axis == 0)
|
||||
verts.push_back({ glm::vec3(0.0f, circle.x, circle.y) + offset, color });
|
||||
else if (axis == 1)
|
||||
verts.push_back({ glm::vec3(circle.x, 0.0f, circle.y) + offset, color });
|
||||
else
|
||||
verts.push_back({ glm::vec3(circle.x, circle.y, 0.0f) + offset, color });
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
indices.push_back(verts.size() - 2);
|
||||
indices.push_back(verts.size() - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
glm::vec3 offset_top(0.0f, 0.0f, half_height);
|
||||
AddArc(0, offset_top, 0, 4);
|
||||
AddArc(1, offset_top, 0, 4);
|
||||
AddArc(2, offset_top, 0, 8);
|
||||
|
||||
glm::vec3 offset_bottom(0.0f, 0.0f, -half_height);
|
||||
AddArc(0, offset_bottom, 4, 8);
|
||||
AddArc(1, offset_bottom, 4, 8);
|
||||
AddArc(2, offset_bottom, 0, 8);
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
glm::vec3 top(0.0f, 0.0f, half_height);
|
||||
|
||||
float o = ((i % 2) ? radius : -radius);
|
||||
|
||||
if (i < 2)
|
||||
top.y = o;
|
||||
else
|
||||
top.x = o;
|
||||
|
||||
glm::vec3 bottom = top; bottom.z = -half_height;
|
||||
|
||||
verts.push_back({ top, color });
|
||||
verts.push_back({ bottom, color });
|
||||
|
||||
indices.push_back(verts.size() - 2);
|
||||
indices.push_back(verts.size() - 1);
|
||||
}
|
||||
|
||||
|
||||
debug_wire_va_ = std::make_unique<gfx::VertexArray>(gfx::VA_POSITION | gfx::VA_COLOR, gfx::VF_CREATE_EBO);
|
||||
debug_wire_va_->SetVBOData(verts.data(), verts.size() * sizeof(CapsuleVertex));
|
||||
debug_wire_va_->SetIndices(indices.data(), indices.size());
|
||||
}
|
||||
|
||||
void game::Entity::CreateOtherOccurence(const Portal& portal)
|
||||
{
|
||||
other_occu_.reset();
|
||||
@ -231,6 +321,8 @@ game::EntityOccurrence::EntityOccurrence(Entity* entity, const CreateOccurrenceP
|
||||
|
||||
// compute inverse normalized basis
|
||||
inv_normal_basis_ = glm::inverse(normal_basis_);
|
||||
|
||||
sector_->AddEntityOccurrence(this);
|
||||
}
|
||||
|
||||
bool game::EntityOccurrence::Sweep(const glm::vec3& target_position, float& hit_fraction, glm::vec3& hit_normal, const Portal** hit_portal)
|
||||
@ -260,3 +352,13 @@ const game::LightInfluences& game::EntityOccurrence::GetLights()
|
||||
entity_->UpdateLights();
|
||||
return lights_;
|
||||
}
|
||||
|
||||
bool game::EntityOccurrence::IsPrimary() const
|
||||
{
|
||||
return &entity_->GetOccurrence() == this;
|
||||
}
|
||||
|
||||
game::EntityOccurrence::~EntityOccurrence()
|
||||
{
|
||||
sector_->RemoveEntityOccurrence(this);
|
||||
}
|
||||
|
||||
@ -65,6 +65,13 @@ namespace game
|
||||
|
||||
const glm::mat3& GetBasis() const { return basis_; }
|
||||
const glm::mat3& GetInvBasis() const { return inv_basis_; }
|
||||
|
||||
Entity& GetEntity() { return *entity_; }
|
||||
const Entity& GetEntity() const { return *entity_; }
|
||||
|
||||
bool IsPrimary() const;
|
||||
|
||||
~EntityOccurrence();
|
||||
};
|
||||
|
||||
class Entity
|
||||
@ -83,6 +90,8 @@ namespace game
|
||||
glm::vec3 light_trace_offset_; // In entity space
|
||||
bool lights_valid_;
|
||||
|
||||
std::unique_ptr<gfx::VertexArray> debug_wire_va_;
|
||||
|
||||
public:
|
||||
Entity(World* world, size_t sector_idx, const CapsuleShape& capsule_shape, const glm::vec3& position);
|
||||
|
||||
@ -99,12 +108,16 @@ namespace game
|
||||
const CapsuleShape& GetCapsuleShape() const { return capsule_; }
|
||||
EntityOccurrence& GetOccurrence() { return *occu_; }
|
||||
|
||||
const gfx::VertexArray& GetDebugWireVA();
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<EntityOccurrence> CreateOccurrence(const CreateOccurrenceParams& params)
|
||||
{
|
||||
return std::make_unique<EntityOccurrence>(this, params);
|
||||
}
|
||||
|
||||
virtual void CreateDebugWireVA();
|
||||
|
||||
private:
|
||||
void CreateOtherOccurence(const Portal& portal);
|
||||
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
#include "sector.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
#include <span>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
@ -13,7 +17,9 @@ game::Sector::Sector(World* world, size_t idx, std::shared_ptr<assets::SectorDef
|
||||
mesh_(def_->GetMesh()),
|
||||
|
||||
bt_col_dispatcher_(&bt_col_cfg_),
|
||||
bt_world_(&bt_col_dispatcher_, &bt_broad_phase_, &bt_col_cfg_)
|
||||
bt_world_(&bt_col_dispatcher_, &bt_broad_phase_, &bt_col_cfg_),
|
||||
|
||||
minimap_va_(gfx::VA_POSITION | gfx::VA_COLOR, gfx::VF_CREATE_EBO)
|
||||
{
|
||||
// Create Bullet collision mesh
|
||||
bt_mesh_col_obj_.setCollisionShape(mesh_->GetCollisionMesh()->GetShape());
|
||||
@ -132,7 +138,7 @@ static void LinkPortal(game::Portal& p1, game::Portal& p2, int flags) {
|
||||
p1.tr_scale = p2.scale / p1.scale;
|
||||
}
|
||||
|
||||
void game::Sector::LinkPortals(Sector& s1, size_t idx1, Sector& s2, size_t idx2, int flags)
|
||||
void game::Sector::LinkPortals(Sector& s1, size_t idx1, Sector& s2, size_t idx2, int flags, uint32_t color)
|
||||
{
|
||||
Portal& p1 = s1.portals_[idx1];
|
||||
Portal& p2 = s2.portals_[idx2];
|
||||
@ -143,10 +149,12 @@ void game::Sector::LinkPortals(Sector& s1, size_t idx1, Sector& s2, size_t idx2,
|
||||
}
|
||||
|
||||
LinkPortal(p1, p2, flags);
|
||||
p1.color = color;
|
||||
|
||||
if (&p1 != &p2)
|
||||
{
|
||||
LinkPortal(p2, p1, flags);
|
||||
p2.color = color;
|
||||
}
|
||||
|
||||
}
|
||||
@ -444,6 +452,119 @@ void game::Sector::Bake()
|
||||
{
|
||||
GenerateAllLights();
|
||||
BakeLightmap();
|
||||
CreateMinimapVA();
|
||||
}
|
||||
|
||||
void game::Sector::AddEntityOccurrence(EntityOccurrence* occu)
|
||||
{
|
||||
occus_.insert(occu);
|
||||
}
|
||||
|
||||
void game::Sector::RemoveEntityOccurrence(EntityOccurrence* occu)
|
||||
{
|
||||
occus_.erase(occu);
|
||||
}
|
||||
|
||||
struct MinimapVertex
|
||||
{
|
||||
glm::vec3 position;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
void game::Sector::CreateMinimapVA()
|
||||
{
|
||||
auto verts = mesh_->GetVertices();
|
||||
auto tris = mesh_->GetTriangles();
|
||||
|
||||
std::vector<MinimapVertex> mm_verts;
|
||||
std::vector<uint32_t> mm_indices;
|
||||
std::map<size_t, size_t> vert_map; // Maps original vertex index to minimap vertex index
|
||||
std::set<std::pair<size_t, size_t>> edges; // Set of edges to avoid duplicates
|
||||
|
||||
for (const assets::MeshTriangle& tri : tris)
|
||||
{
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
{
|
||||
size_t v_idx[2] = { tri.vert[i], tri.vert[(i + 1) % 3] };
|
||||
|
||||
if (v_idx[0] > v_idx[1])
|
||||
{
|
||||
std::swap(v_idx[0], v_idx[1]); // Smaller index first
|
||||
}
|
||||
|
||||
auto edge = std::make_pair(v_idx[0], v_idx[1]);
|
||||
if (edges.find(edge) != edges.end())
|
||||
{
|
||||
continue; // Edge already in
|
||||
}
|
||||
|
||||
edges.insert(edge);
|
||||
|
||||
size_t mm_v_idx[2];
|
||||
for (size_t j = 0; j < 2; j++)
|
||||
{
|
||||
auto it = vert_map.find(v_idx[j]);
|
||||
if (it != vert_map.end())
|
||||
{
|
||||
mm_v_idx[j] = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& v = verts[v_idx[j]];
|
||||
|
||||
MinimapVertex mmv;
|
||||
mmv.position = v.pos;
|
||||
mmv.color = 0xFF444444;
|
||||
mm_v_idx[j] = mm_verts.size();
|
||||
|
||||
mm_verts.push_back(mmv);
|
||||
vert_map[v_idx[j]] = mm_v_idx[j];
|
||||
}
|
||||
}
|
||||
|
||||
// Insert edge indices
|
||||
for (size_t j = 0; j < 2; j++)
|
||||
{
|
||||
mm_indices.push_back(static_cast<uint32_t>(mm_v_idx[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add portal edges
|
||||
for (const Portal& portal : portals_)
|
||||
{
|
||||
if (!portal.link)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t first = mm_verts.size();
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
MinimapVertex mmv;
|
||||
mmv.position = portal.verts[i];
|
||||
mmv.color = portal.color;
|
||||
mm_verts.push_back(mmv);
|
||||
}
|
||||
|
||||
// Add edges
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
mm_indices.push_back(first + i);
|
||||
mm_indices.push_back(first + ((i + 1) % 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
minimap_va_.SetVBOData(mm_verts.data(), mm_verts.size() * sizeof(MinimapVertex));
|
||||
minimap_va_.SetIndices(mm_indices.data(), mm_indices.size());
|
||||
|
||||
// Compute AABB
|
||||
for (size_t i = 0; i < mm_verts.size(); i++)
|
||||
{
|
||||
aabb_.AddPoint(mm_verts[i].position);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void game::Sector::GenerateAllLights()
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "assets/sectordef.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <btBulletCollisionCommon.h>
|
||||
|
||||
namespace game
|
||||
@ -46,6 +47,8 @@ namespace game
|
||||
std::unique_ptr<btCollisionShape> bt_col_shape; // Bullet collision shape
|
||||
std::unique_ptr<btCollisionObject> bt_col_obj; // Bullet collision object
|
||||
CollisionObjectData col_data;
|
||||
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
enum LinkPortalFlags
|
||||
@ -70,6 +73,8 @@ namespace game
|
||||
glm::vec3 sun_color;
|
||||
};
|
||||
|
||||
class EntityOccurrence;
|
||||
|
||||
class Sector
|
||||
{
|
||||
World* world_;
|
||||
@ -94,6 +99,11 @@ namespace game
|
||||
btDbvtBroadphase bt_broad_phase_;
|
||||
btCollisionWorld bt_world_;
|
||||
|
||||
gfx::VertexArray minimap_va_;
|
||||
collision::AABB3 aabb_;
|
||||
|
||||
std::set<EntityOccurrence*> occus_;
|
||||
|
||||
public:
|
||||
Sector(World* world, size_t idx, std::shared_ptr<assets::SectorDef> def);
|
||||
|
||||
@ -114,7 +124,10 @@ namespace game
|
||||
const Portal& GetPortal(size_t idx) const { return portals_[idx]; }
|
||||
const size_t GetNumPortals() const { return portals_.size(); }
|
||||
|
||||
static void LinkPortals(Sector& s1, size_t idx1, Sector& s2, size_t idx2, int flags);
|
||||
const collision::AABB3& GetAABB() const { return aabb_; }
|
||||
const gfx::VertexArray& GetMinimapVA() const { return minimap_va_; }
|
||||
|
||||
static void LinkPortals(Sector& s1, size_t idx1, Sector& s2, size_t idx2, int flags, uint32_t color = 0);
|
||||
|
||||
bool SweepCapsule(
|
||||
const btCapsuleShapeZ& capsule,
|
||||
@ -132,9 +145,14 @@ namespace game
|
||||
|
||||
void Bake();
|
||||
|
||||
void AddEntityOccurrence(EntityOccurrence* occu);
|
||||
void RemoveEntityOccurrence(EntityOccurrence* occu);
|
||||
const std::set<EntityOccurrence*>& GetEntityOccurrences() const { return occus_; }
|
||||
|
||||
private:
|
||||
void GenerateAllLights();
|
||||
void BakeLightmap();
|
||||
void CreateMinimapVA();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -13,6 +13,23 @@ size_t game::World::AddSector(std::shared_ptr<assets::SectorDef> def)
|
||||
return idx;
|
||||
}
|
||||
|
||||
static const uint32_t PORTAL_COLORS[] = {
|
||||
0xFF0000FF, // Red
|
||||
0xFF00FF00, // Green
|
||||
0xFFFF0000, // Blue
|
||||
0xFF00FFFF, // Yellow
|
||||
0xFFFF00FF, // Magenta
|
||||
0xFFFFFF00, // Cyan
|
||||
0xFFFFFFFF, // White
|
||||
0xFFFFA500, // Orange
|
||||
0xFF800080, // Purple
|
||||
0xFF808080, // Gray
|
||||
0xFF008000, // Dark Green
|
||||
0xFF000080, // Dark Blue
|
||||
0xFF800000, // Dark Red
|
||||
0xFF808000, // Olive
|
||||
};
|
||||
|
||||
void game::World::LinkPortals(size_t sector1, const std::string& portal_name1, size_t sector2, const std::string& portal_name2, int flags)
|
||||
{
|
||||
Sector& s1 = *sectors_[sector1];
|
||||
@ -25,9 +42,12 @@ void game::World::LinkPortals(size_t sector1, const std::string& portal_name1, s
|
||||
throw std::runtime_error("Invalid portal names for linking");
|
||||
}
|
||||
|
||||
Sector::LinkPortals(s1, p1, s2, p2, flags);
|
||||
size_t color_idx = (next_portal_color_++) % (sizeof(PORTAL_COLORS) / sizeof(PORTAL_COLORS[0]));
|
||||
|
||||
Sector::LinkPortals(s1, p1, s2, p2, flags, PORTAL_COLORS[color_idx]);
|
||||
}
|
||||
|
||||
|
||||
void game::World::Bake()
|
||||
{
|
||||
for (auto& sector : sectors_)
|
||||
|
||||
@ -16,6 +16,8 @@ namespace game
|
||||
|
||||
float time_ = 0.0f; // Game time
|
||||
|
||||
size_t next_portal_color_ = 0;
|
||||
|
||||
public:
|
||||
World();
|
||||
|
||||
@ -35,6 +37,7 @@ namespace game
|
||||
|
||||
void Update(float dt);
|
||||
|
||||
size_t GetNumSectors() const { return sectors_.size(); }
|
||||
Sector& GetSector(size_t idx) { return *sectors_[idx]; }
|
||||
const Sector& GetSector(size_t idx) const { return *sectors_[idx]; }
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ gfx::Renderer::Renderer()
|
||||
ShaderSources::MakeShader(portal_shader_.shader, SS_PORTAL_VERT, SS_PORTAL_FRAG);
|
||||
ShaderSources::MakeShader(mesh_shader_.shader, SS_MESH_VERT, SS_MESH_FRAG);
|
||||
ShaderSources::MakeShader(skel_mesh_shader_.shader, SS_SKEL_MESH_VERT, SS_SKEL_MESH_FRAG);
|
||||
ShaderSources::MakeShader(solid_shader_, SS_SOLID_VERT, SS_SOLID_FRAG);
|
||||
proj_ = glm::mat4(1.0f); // Initialize projection matrix to identity
|
||||
|
||||
SetupPortalVAO();
|
||||
@ -36,6 +37,9 @@ void gfx::Renderer::Begin(size_t width, size_t height)
|
||||
glViewport(0, 0, width, height);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
screen_width_ = width;
|
||||
screen_height_ = height;
|
||||
}
|
||||
|
||||
void gfx::Renderer::DrawWorld(
|
||||
@ -131,6 +135,10 @@ void gfx::Renderer::DrawWorld(
|
||||
}
|
||||
}
|
||||
|
||||
if (show_minimap)
|
||||
{
|
||||
DrawMinimap(world, sector_idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -462,3 +470,108 @@ void gfx::Renderer::DrawMeshInstance(const DrawSectorParams& params, game::MeshI
|
||||
}
|
||||
}
|
||||
|
||||
void gfx::Renderer::DrawMinimap(const game::World& world, size_t current_sector_idx)
|
||||
{
|
||||
const size_t MAX_SECTORS = 32;
|
||||
|
||||
size_t num_sectors = world.GetNumSectors();
|
||||
|
||||
if (num_sectors > MAX_SECTORS)
|
||||
{
|
||||
num_sectors = MAX_SECTORS; // Limit number of sectors to draw
|
||||
}
|
||||
|
||||
const float margin = 1.0f;
|
||||
glm::vec2 mm_size(margin, 0.0f);
|
||||
|
||||
for (size_t i = 0; i < num_sectors; ++i)
|
||||
{
|
||||
const game::Sector& sector = world.GetSector(i);
|
||||
const collision::AABB3& aabb = sector.GetAABB();
|
||||
glm::vec3 size = aabb.max - aabb.min;
|
||||
|
||||
//if (size.x > size.y)
|
||||
//{
|
||||
// std::swap(size.x, size.y); // Will be rotated
|
||||
//}
|
||||
|
||||
mm_size.y = glm::max(mm_size.y, size.y + margin * 2.0f);
|
||||
mm_size.x += size.x + margin;
|
||||
}
|
||||
|
||||
glm::vec2 screen_size = glm::vec2((float)screen_width_, (float)screen_height_);
|
||||
float mm_scale = 24.0f; // pixels / m
|
||||
|
||||
glUseProgram(solid_shader_->GetId());
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
//glm::vec2 global_offset(-mm_size.x + screen_size.x * 0.5f / mm_scale, -mm_size.y + screen_size.y * 0.5f / mm_scale);
|
||||
glm::vec2 global_offset = screen_size / mm_scale * 0.5f - mm_size;
|
||||
|
||||
for (size_t i = 0; i < num_sectors; ++i)
|
||||
{
|
||||
const game::Sector& sector = world.GetSector(i);
|
||||
const VertexArray& va = sector.GetMinimapVA();
|
||||
const collision::AABB3& aabb = sector.GetAABB();
|
||||
glm::vec3 size = aabb.max - aabb.min;
|
||||
|
||||
glm::mat4 view(1.0f);
|
||||
|
||||
glm::vec2 ortho_scale = mm_scale / screen_size * 2.0f;
|
||||
|
||||
glm::vec2 ortho_offset(-aabb.min.x, -aabb.min.y);
|
||||
ortho_offset.y += (mm_size.y - size.y) * 0.5f; // Center vertically
|
||||
//glm::vec2 ortho_offset(10.0f);
|
||||
//ortho_offset += size * 0.5f;
|
||||
ortho_offset += global_offset;
|
||||
ortho_offset *= ortho_scale;
|
||||
|
||||
glm::mat4 proj{
|
||||
ortho_scale.x, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, ortho_scale.y, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.01f, 0.0f,
|
||||
ortho_offset.x, ortho_offset.y, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
glm::mat4 view_proj = proj;
|
||||
|
||||
|
||||
|
||||
glBindVertexArray(va.GetVAOId());
|
||||
glUniformMatrix4fv(solid_shader_->U(gfx::SU_VIEW_PROJ), 1, GL_FALSE, &view_proj[0][0]);
|
||||
glUniform4fv(solid_shader_->U(gfx::SU_COLOR), 1, &glm::vec4(1.0f)[0]);
|
||||
glDrawElements(GL_LINES, va.GetNumIndices(), GL_UNSIGNED_INT, 0);
|
||||
|
||||
for (const auto& occus = sector.GetEntityOccurrences(); const auto& occu : occus)
|
||||
{
|
||||
glm::mat4 model = occu->GetBasis();
|
||||
model[3] = glm::vec4(occu->GetPosition(), 1.0f);
|
||||
|
||||
const VertexArray& va = occu->GetEntity().GetDebugWireVA();
|
||||
|
||||
glm::mat4 mvp = view_proj * model;
|
||||
|
||||
glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (!occu->IsPrimary())
|
||||
{
|
||||
color *= 0.5f;
|
||||
color.a = 1.0f;
|
||||
}
|
||||
|
||||
glBindVertexArray(va.GetVAOId());
|
||||
glUniformMatrix4fv(solid_shader_->U(gfx::SU_VIEW_PROJ), 1, GL_FALSE, &mvp[0][0]);
|
||||
glUniform4fv(solid_shader_->U(gfx::SU_COLOR), 1, &color[0]);
|
||||
glDrawElements(GL_LINES, va.GetNumIndices(), GL_UNSIGNED_INT, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
global_offset.x += size.x + margin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -45,11 +45,14 @@ namespace gfx
|
||||
float aspect,
|
||||
float fov);
|
||||
|
||||
bool show_minimap = false;
|
||||
|
||||
private:
|
||||
SectorShader sector_shader_;
|
||||
SectorShader portal_shader_;
|
||||
SectorShader mesh_shader_;
|
||||
SectorShader skel_mesh_shader_;
|
||||
std::unique_ptr<Shader> solid_shader_;
|
||||
|
||||
std::shared_ptr<VertexArray> portal_vao_;
|
||||
void SetupPortalVAO();
|
||||
@ -60,6 +63,7 @@ namespace gfx
|
||||
// If the distance is smaller, portal plane is shifted to avoid clipping by near plane
|
||||
float min_portal_distance_;
|
||||
|
||||
size_t screen_width_, screen_height_;
|
||||
glm::mat4 proj_;
|
||||
size_t last_sector_id;
|
||||
const Shader* current_shader_;
|
||||
@ -76,6 +80,7 @@ namespace gfx
|
||||
|
||||
void DrawMeshInstance(const DrawSectorParams& params, game::MeshInstance& mesh_instance, const glm::mat4& transform, const game::LightInfluences& lights);
|
||||
|
||||
void DrawMinimap(const game::World& world, size_t current_sector_idx);
|
||||
};
|
||||
|
||||
}
|
||||
@ -16,6 +16,7 @@ static const char* const s_uni_names[] = {
|
||||
"u_light_positions", // SU_LIGHT_POSITIONS
|
||||
"u_light_colors_rs", // SU_LIGHT_COLORS_RS
|
||||
"u_ambient_light", // SU_AMBIENT_LIGHT
|
||||
"u_color" // SU_COLOR
|
||||
};
|
||||
|
||||
// Vytvori shader z daneho zdroje
|
||||
|
||||
@ -21,6 +21,7 @@ namespace gfx
|
||||
SU_LIGHT_POSITIONS,
|
||||
SU_LIGHT_COLORS_RS,
|
||||
SU_AMBIENT_LIGHT,
|
||||
SU_COLOR,
|
||||
|
||||
SU_COUNT
|
||||
};
|
||||
|
||||
@ -287,6 +287,37 @@ void main() {
|
||||
|
||||
)GLSL",
|
||||
|
||||
// SS_SOLID_VERT
|
||||
SHADER_HEADER
|
||||
R"GLSL(
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 2) in vec4 a_color;
|
||||
|
||||
uniform mat4 u_view_proj;
|
||||
uniform vec4 u_color;
|
||||
|
||||
out vec4 v_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_view_proj * vec4(a_pos, 1.0);
|
||||
v_color = a_color * u_color;
|
||||
}
|
||||
)GLSL",
|
||||
|
||||
// SS_SOLID_FRAG
|
||||
SHADER_HEADER
|
||||
R"GLSL(
|
||||
in vec4 v_color;
|
||||
|
||||
layout (location = 0) out vec4 o_color;
|
||||
|
||||
void main() {
|
||||
o_color = v_color;
|
||||
}
|
||||
|
||||
)GLSL",
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Vrati zdrojovy kod shaderu
|
||||
|
||||
@ -19,6 +19,9 @@ namespace gfx
|
||||
SS_SKEL_MESH_VERT,
|
||||
SS_SKEL_MESH_FRAG,
|
||||
|
||||
SS_SOLID_VERT,
|
||||
SS_SOLID_FRAG,
|
||||
|
||||
};
|
||||
|
||||
class ShaderSources
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user