added cameras

This commit is contained in:
Jay Robson 2024-03-18 21:57:06 +11:00
parent ddec7eeb9d
commit c85984fc7f
60 changed files with 811 additions and 388 deletions

BIN
assets/scene.blend (Stored with Git LFS)

Binary file not shown.

BIN
assets/scene.glb (Stored with Git LFS)

Binary file not shown.

View File

@ -1,26 +1,26 @@
#version 460 core
uniform int samples;
uniform sampler2D tex;
uniform vec2 direction;
uniform int samples;
in vec2 texPos;
in vec2 FragPos;
out vec4 FragColour;
void main()
{
vec2 texel_size = 1.f / vec2(textureSize(tex, 0));
float samples_n = pow(samples * 2 + 1, 2);
vec4 colour;
for(int x = -samples; x <= samples; x++)
for(int y = -samples; y <= samples; y++)
int radius = (samples - 1) / 2;
ivec2 size = textureSize(tex, 0);
vec2 step = direction / size;
vec4 sum = vec4(0.f);
for(int i = -radius; i <= radius; i++)
{
vec2 off = texel_size * vec2(x, y);
colour += texture2D(tex, texPos + off);
vec2 offset = vec2(i) * step;
sum += texture(tex, FragPos + offset);
}
FragColour = vec4((colour / samples_n).rgb, 1);
FragColour = sum / float(samples);
}

View File

@ -1,14 +0,0 @@
#version 460 core
layout (location = 1) in vec2 aTexPos;
layout (location = 2) in vec4 aPos;
out vec2 texPos;
void main()
{
texPos = aTexPos;
gl_Position = aPos;
}

View File

@ -122,23 +122,26 @@ void main()
vec3 N = normalize(vin.normal);
vec3 V = normalize(camera_pos - vin.pos.xyz);
vec3 F0 = vec3(0.04f);
F0 = mix(F0, albedo_lin, metalness);
vec3 F0 = mix(vec3(0.04f), albedo_lin, metalness);
vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness;
vec3 Lo = vec3(0.f);
for(int i = 0; i < lights_count; i++)
{
Light l = lights[i];
float light_m;
vec3 L = normalize(l.pos.xyz - vin.pos);
float d = length(vin.pos - l.pos.xyz);
vec3 L = (l.pos.xyz - vin.pos) / d;
float light_m;
if(shadows_enabled)
{
float max_d = texture(shadow_maps[i], -L).r * far_plane;
light_m = Ramp(d - max_d, 0.f, 2.5e-2f, 1.f, 0.f);
if(light_m <= 0.f) continue;
if(light_m <= 0.f)
{
continue;
}
}
else
@ -162,14 +165,12 @@ void main()
vec3 numerator = NDF * G * F;
float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 1e-4f;
vec3 specular = numerator / denominator;
// add to outgoing radiance Lo
float NdotL = max(dot(N, L), 0.f);
Lo += (kD * albedo_lin / PI + specular) * radiance * NdotL * light_m;
}
vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness;
vec3 light = LinRGB_To_sRGB(ambient + Lo);
light = mix(light, albedo.rgb, luminance);

View File

@ -0,0 +1,21 @@
#version 460 core
const vec2 QuadVertices[6] = vec2[6](
vec2(-1.0, 1.0),
vec2(-1.0, -1.0),
vec2( 1.0, -1.0),
vec2(-1.0, 1.0),
vec2( 1.0, -1.0),
vec2( 1.0, 1.0)
);
out vec2 FragPos;
void main()
{
vec2 vertex = QuadVertices[gl_VertexID];
FragPos = vertex * 0.5f + 0.5f;
gl_Position = vec4(vertex, 0.f, 1.f);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -33,7 +33,7 @@ void Generator::update(double dt)
double energy_input = turbine->extract_energy();
double energy_friction = get_rpm() / 60 * dt * friction;
double work = Util::Math::j_to_ms2(energy_input - energy_friction, mass);
phase = std::fmod(phase + Util::Math::map( get_rpm(), 0, 3600, 0, 120 * M_PI ) * dt, 2 * M_PI);
phase = std::fmod(phase + Util::Math::map( get_rpm(), 0, 3600, 0, 120 * M_PI ) * dt, 4 * M_PI);
// do energy transfer stuff here
if(breaker_closed)

View File

@ -3,7 +3,7 @@
#include <GLFW/glfw3.h>
#include "camera.hpp"
#include "mesh/mesh.hpp"
#include "data/mesh.hpp"
#include "input/keyboard.hpp"
#include "../util/math.hpp"
@ -19,7 +19,7 @@ static bool on_ground = false;
static double yaw = 0, pitch = 0;
static glm::vec<3, double> pos(0, 0, 2);
static glm::vec<3, double> velocity(0);
static Mesh collision_scene;
static Data::Mesh collision_scene;
static glm::mat4 camera_mat;
Json::Value Camera::serialize()
@ -79,7 +79,12 @@ glm::vec<3, double> Camera::get_pos()
return pos;
}
void Camera::init(const Model& model)
glm::vec<3, double> Camera::get_pos_base()
{
return pos - glm::vec<3, double>(0, 0, 1.5);
}
void Camera::init(const Data::Model& model)
{
collision_scene = model.load("collision");
}

View File

@ -5,13 +5,14 @@
#include <json/json.h>
#include "../system.hpp"
#include "mesh/model.hpp"
#include "data/model.hpp"
namespace Sim::Graphics::Camera
{
glm::vec<3, double> get_normal();
glm::vec<3, double> get_pos();
glm::vec<3, double> get_pos_base();
glm::mat4 get_matrix();
double get_pitch();
double get_yaw();
@ -19,7 +20,7 @@ double get_yaw();
Json::Value serialize();
void load(const Json::Value& node);
void init(const Model& model);
void init(const Data::Model& model);
void rotate(double pitch, double yaw);
void move(double x, double y, double z);
void update(double dt);

View File

@ -9,7 +9,7 @@
#include "arrays.hpp"
#include "font.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
static void* ptr_diff(void* a, void* b)
{

View File

@ -4,7 +4,7 @@
#include <glm/matrix.hpp>
#include <ostream>
namespace Sim::Graphics::Arrays
namespace Sim::Graphics::Data::Arrays
{
struct Vertex

View File

@ -0,0 +1,22 @@
#pragma once
#include <glm/matrix.hpp>
namespace Sim::Graphics::Data
{
struct Camera
{
glm::vec3 pos;
glm::vec3 look;
glm::vec3 up;
float fov;
float pitch = 0;
float yaw = 0;
float zoom = 1;
};
};

View File

@ -13,7 +13,7 @@
#include "arrays.hpp"
#include "font.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
struct Character
{

View File

@ -6,7 +6,7 @@
#include <string>
#include <sstream>
namespace Sim::Graphics::Font
namespace Sim::Graphics::Data::Font
{
void init();

View File

@ -10,7 +10,7 @@
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
static glm::mat4 shadow_mats[6];
@ -64,12 +64,20 @@ void GLLight::render()
glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos);
glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(0, 0, size, size);
Window::render_scene();
}
void GLLight::render_player()
{
glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos);
glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, size, size);
Window::render_player();
}
void GLLight::init()
{
glm::mat4 shadow_proj = glm::perspective<float>(M_PI * 0.5f, 1.0f, 0.01f, 100.f);

View File

@ -3,7 +3,7 @@
#include "light.hpp"
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
struct GLLight
@ -22,6 +22,7 @@ struct GLLight
static void init();
void render();
void render_player();
};
};

View File

@ -8,7 +8,7 @@
#include "../camera.hpp"
#include "../../util/streams.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
constexpr static void init(GLMesh* m)
{
@ -52,20 +52,25 @@ GLMesh::~GLMesh()
if(vao) glDeleteVertexArrays(1, &vao);
}
void GLMesh::bind(bool bind_ssbo)
void GLMesh::bind()
{
init(this);
glBindVertexArray(vao);
if(ssbo_size > 0 && bind_ssbo)
{
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo);
}
}
void GLMesh::set(const Mesh& m, int mode, bool send_ssbo)
void GLMesh::bind_ssbo()
{
if(!ssbo)
{
glGenBuffers(1, &ssbo);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo);
}
void GLMesh::set(const Mesh& m, int mode)
{
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
@ -74,17 +79,6 @@ void GLMesh::set(const Mesh& m, int mode, bool send_ssbo)
this->size = m.indices.size();
this->ssbo_size = m.transforms.size();
if(ssbo_size > 0 && send_ssbo)
{
if(ssbo == 0)
{
glGenBuffers(1, &ssbo);
}
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, m.transforms.size() * sizeof(m.transforms[0]), &m.transforms[0], mode);
}
}
void GLMesh::render()

View File

@ -8,7 +8,7 @@
#include <glm/matrix.hpp>
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
struct GLMesh
@ -23,8 +23,9 @@ struct GLMesh
GLMesh(const GLMesh& o) = delete;
~GLMesh();
void bind(bool bind_ssbo = true);
void set(const Mesh& m, int mode, bool send_ssbo = true);
void bind();
void bind_ssbo();
void set(const Mesh& m, int mode);
void render(int type);
void render();
};

View File

@ -3,7 +3,7 @@
#include <glm/matrix.hpp>
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
struct Light

View File

@ -9,7 +9,7 @@
#include <iostream>
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
Mesh::Mesh()
{
@ -178,15 +178,28 @@ bool ray_intersects_triangle(vec3 ray_origin,
bool Mesh::check_focus(double len) const
{
if(!Focus::is_triggered())
{
return false;
}
auto near = Focus::get_trigger_near();
auto far = Focus::get_trigger_far();
return Focus::is_triggered() && check_intersect(near, glm::normalize(far - near) * len);
return check_intersect(near, glm::normalize(far - near) * len);
}
bool Mesh::check_focus() const
bool Mesh::check_focus_hold(double len)
{
return check_focus(2.5);
if(!Focus::is_triggered() && (!focus || Focus::is_triggered_release()))
{
return focus = false;
}
auto near = Focus::get_trigger_near();
auto far = Focus::get_trigger_far();
return focus = check_intersect(near, glm::normalize(far - near) * len);
}
bool Mesh::check_intersect(vec3 pos, vec3 path) const
@ -329,7 +342,7 @@ Mesh Mesh::to_lines() const
return m;
}
std::ostream& Sim::Graphics::operator<<(std::ostream& os, const Mesh& m)
std::ostream& Sim::Graphics::Data::operator<<(std::ostream& os, const Mesh& m)
{
os << "Mesh(\n";
os << " Vertices(\n";

View File

@ -12,7 +12,7 @@
#include "arrays.hpp"
#include "light.hpp"
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
struct Mesh
@ -20,6 +20,7 @@ struct Mesh
std::vector<Arrays::Vertex> vertices;
std::vector<unsigned int> indices;
std::vector<glm::mat4> transforms;
bool focus = false;
Mesh();
@ -31,8 +32,8 @@ struct Mesh
Mesh& add(const Mesh& o, glm::mat4 mat = glm::mat4(1), bool bake = false);
Mesh to_lines() const;
bool check_focus() const;
bool check_focus(double len) const;
bool check_focus(double len = 2.5) const;
bool check_focus_hold(double len = 2.5);
bool check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const;
glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const;

View File

@ -1,9 +1,9 @@
#pragma once
#include "../mesh/model.hpp"
#include "model.hpp"
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
class MeshGen

View File

@ -14,7 +14,7 @@
#include "model.hpp"
#include "../../util/streams.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
struct ProcState
{
@ -176,10 +176,10 @@ static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene)
glm::mat4 convert_mat(aiMatrix4x4 m)
{
return {
m.a1, m.a2, m.a3, m.a4,
m.b1, m.b2, m.b3, m.b4,
m.c1, m.c2, m.c3, m.c4,
m.d1, m.d2, m.d3, m.d4
m.a1, m.b1, m.c1, m.d1,
m.a2, m.b2, m.c2, m.d2,
m.a3, m.b3, m.c3, m.d3,
m.a4, m.b4, m.c4, m.d4
};
}
@ -213,7 +213,7 @@ static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiSce
if(node->mNumMeshes > 0)
{
state.transforms.push_back(glm::transpose(mat));
state.transforms.push_back(mat);
}
}
@ -258,7 +258,7 @@ glm::mat4 get_transforms(const aiNode* node)
return mat;
}
glm::mat4 Model::get_matrix(const char* name) const
glm::mat4 Model::load_matrix(const char* name) const
{
return get_transforms(scene->mRootNode->FindNode(name));
}
@ -280,18 +280,34 @@ Model::Model(std::string base, std::string filename) : base(base)
for(int i = 0; i < scene->mNumLights; i++)
{
aiLight* light = scene->mLights[i];
glm::mat4 mat = get_matrix(light->mName.C_Str());
glm::mat4 mat = load_matrix(light->mName.C_Str());
auto [x, y, z] = light->mPosition;
auto [r, g, b] = light->mColorDiffuse;
glm::vec4 pos = glm::vec4(x, y, z, 1) * mat;
glm::vec4 pos = mat * glm::vec4(x, y, z, 1);
lights.push_back({
glm::vec3(pos),
{r, g, b},
});
}
for(int i = 0; i < scene->mNumCameras; i++)
{
aiCamera* camera = scene->mCameras[i];
glm::mat4 mat = load_matrix(camera->mName.C_Str());
auto [x, y, z] = camera->mPosition;
auto [dx, dy, dz] = camera->mLookAt;
auto [ux, uy, uz] = camera->mUp;
glm::vec4 pos = mat * glm::vec4(x, y, z, 1);
glm::vec3 look = glm::normalize(glm::mat3(mat) * glm::vec3(dx, dy, dz));
glm::vec3 up = glm::normalize(glm::mat3(mat) * glm::vec3(ux, uy, uz));
cameras.push_back({.pos=glm::vec3(pos), .look=look, .up=up, .fov=camera->mHorizontalFOV});
}
}
Mesh Model::load(const char* name, glm::mat4 mat) const

View File

@ -3,6 +3,7 @@
#include "mesh.hpp"
#include "light.hpp"
#include "camera.hpp"
#include <string>
#include <vector>
@ -14,7 +15,7 @@
#include <assimp/material.h>
#include <assimp/postprocess.h>
namespace Sim::Graphics
namespace Sim::Graphics::Data
{
class Model
@ -26,6 +27,7 @@ class Model
public:
std::vector<uint64_t> textures;
std::vector<Camera> cameras;
std::vector<Light> lights;
Model(std::string base, std::string filename);
@ -35,7 +37,7 @@ public:
Mesh load_root(glm::mat4 mat) const;
Mesh load(const char* name) const;
Mesh load(const char* name, glm::mat4 mat) const;
glm::mat4 get_matrix(const char* name) const;
glm::mat4 load_matrix(const char* name) const;
};
};

View File

@ -8,7 +8,7 @@
#include "texture.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
static std::unordered_map<std::string, unsigned int> loaded;
unsigned int Texture::handle_white;

View File

@ -3,7 +3,7 @@
#include <string>
namespace Sim::Graphics::Texture
namespace Sim::Graphics::Data::Texture
{
extern unsigned int handle_white;

View File

@ -5,6 +5,7 @@
#include <glm/gtc/matrix_transform.hpp>
using namespace Sim::Graphics::Equipment;
using namespace Sim::Graphics::Data;
Generator::Generator(const Model& model)
{
@ -19,7 +20,7 @@ void Generator::remesh_static(Mesh& rmesh)
void Generator::get_static_transforms(std::vector<glm::mat4>& transforms)
{
Sim::System& sys = *Sim::System::active;
glm::mat4 rot = glm::rotate(glm::mat4(1), (float)sys.loop.generator.get_phase(), glm::vec3(0, 0, 1));
glm::mat4 rot = glm::rotate(glm::mat4(1), (float)sys.loop.generator.get_phase() * 0.5f, glm::vec3(0, 0, 1));
transforms.push_back(rot);
}

View File

@ -1,20 +1,20 @@
#pragma once
#include "../mesh/meshgen.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Equipment
{
class Generator : public MeshGen
class Generator : public Data::MeshGen
{
Mesh g_rotor;
Data::Mesh g_rotor;
public:
Generator(const Model& model);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
Generator(const Data::Model& model);
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
};
};

View File

@ -5,6 +5,7 @@
#include <glm/gtc/matrix_transform.hpp>
using namespace Sim::Graphics::Equipment;
using namespace Sim::Graphics::Data;
Pool::Pool(const Model& model)
{

View File

@ -1,20 +1,20 @@
#pragma once
#include "../mesh/meshgen.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Equipment
{
class Pool : public MeshGen
class Pool : public Data::MeshGen
{
Mesh g_pool;
Data::Mesh g_pool;
public:
Pool(const Model& model);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
Pool(const Data::Model& model);
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
};
};

View File

@ -8,6 +8,7 @@
#include <glm/gtc/matrix_transform.hpp>
using namespace Sim::Graphics::Equipment;
using namespace Sim::Graphics::Data;
Reactor::Reactor(const Model& model)
{
@ -22,6 +23,8 @@ void Reactor::remesh_static(Mesh& rmesh)
double t_sx = -(sys.reactor.width - 1) * t_step / 2.0;
double t_sy = -(sys.reactor.height - 1) * t_step / 2.0;
glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(t_step / 0.4));
for(int i = 0; i < sys.reactor.size; i++)
{
int x = i % sys.reactor.width;
@ -39,12 +42,21 @@ void Reactor::remesh_static(Mesh& rmesh)
if(r->get_colour()[3] != 0)
{
Mesh m1, m2;
m1.add(g_control_rod_base, glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)));
m2.add(g_control_rod_lift, glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)));
glm::mat4 m = glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale;
m1.add(g_control_rod_base, m);
m2.add(g_control_rod_lift, m);
m1.bake_transforms();
m2.bake_transforms();
m2.set_blank_transform();
for(int i = 0; i < m2.vertices.size(); i++)
{
if(g_control_rod_lift.vertices[i].pos.z == 0)
{
m2.vertices[i].transform_id = -1;
}
}
rmesh.add(m1);
rmesh.add(m2);
}

View File

@ -1,20 +1,20 @@
#pragma once
#include "../mesh/meshgen.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Equipment
{
class Reactor : public MeshGen
class Reactor : public Data::MeshGen
{
Mesh g_control_rod_lift, g_control_rod_base;
Data::Mesh g_control_rod_lift, g_control_rod_base;
public:
Reactor(const Model& model);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
Reactor(const Data::Model& model);
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
};
};

View File

@ -24,6 +24,7 @@ static std::unique_ptr<Focus::FocusType> state = nullptr;
static bool mouse_visible = false;
static bool mouse_locked = false;
static bool triggered = false;
static bool triggered_release = false;
void Focus::on_keypress(int key, int sc, int action, int mods)
{
@ -53,8 +54,10 @@ void Focus::on_mouse_button(int button, int action, int mods)
state->on_mouse_button(button, action, mods);
}
if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
if(button == GLFW_MOUSE_BUTTON_LEFT && (action == GLFW_RELEASE || action == GLFW_PRESS))
{
bool t = false;
if(is_mouse_locked() && mouse_visible)
{
double mx, my;
@ -66,14 +69,21 @@ void Focus::on_mouse_button(int button, int action, int mods)
trigger_near = glm::unProject(glm::vec3(mouse, -1), Camera::get_matrix(), Window::projection_matrix, viewport);
trigger_far = glm::unProject(glm::vec3(mouse, 1), Camera::get_matrix(), Window::projection_matrix, viewport);
triggered = true;
t = true;
}
else if(!mouse_visible)
{
trigger_near = Camera::get_pos();
trigger_far = trigger_near + Camera::get_normal();
triggered = true;
t = true;
}
if(t)
{
t = (action == GLFW_PRESS);
triggered_release = !t;
triggered = t;
}
}
}
@ -107,6 +117,7 @@ glm::vec<3, double> Focus::get_trigger_far()
void Focus::update(double dt)
{
triggered = false;
triggered_release = false;
bool c = is_mouse_locked();
@ -194,3 +205,8 @@ bool Focus::is_triggered()
return triggered;
}
bool Focus::is_triggered_release()
{
return triggered_release;
}

View File

@ -24,6 +24,7 @@ struct FocusType
bool is_focused();
void clear_focus();
bool is_triggered();
bool is_triggered_release();
bool is_mouse_locked();
void clear_mouse_locked();
glm::vec<3, double> get_trigger_near();

View File

@ -1,47 +0,0 @@
#include "locations.hpp"
#include <glm/ext/matrix_transform.hpp>
using namespace Sim::Graphics;
const glm::mat4 Locations::monitors[7] = {
(
glm::translate(glm::mat4(1), glm::vec3(-2.9475, -1.7778 + 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(-1.5 + 0.05, 3.9475, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(1 + 0.05, 3.9475, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(3.5 + 0.05, 3.9475, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(6 + 0.05, 3.9475, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(8.9475, 7.0/3.0 - 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
),
(
glm::translate(glm::mat4(1), glm::vec3(8.9475, -1.0/3.0 - 0.05, 3 - 0.05)) *
glm::rotate(glm::mat4(1), glm::radians<float>(-90), glm::vec3(1, 0, 0)) *
glm::rotate(glm::mat4(1), glm::radians<float>(90), glm::vec3(0, 1, 0)) *
glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9))
)
};

View File

@ -1,12 +0,0 @@
#pragma once
#include <glm/matrix.hpp>
namespace Sim::Graphics::Locations
{
extern const glm::mat4 monitors[7];
};

View File

@ -0,0 +1,270 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <cmath>
#include "cctv.hpp"
#include "../shader.hpp"
#include "../window.hpp"
#include "../camera.hpp"
#include "../input/focus.hpp"
#include "../../system.hpp"
#include "../../util/math.hpp"
#include "../../util/streams.hpp"
#define HEIGHT 512
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Graphics;
using namespace Sim;
class FocusCCTV : public Focus::FocusType
{
CCTV* parent;
int zoom = 0;
int rot_pitch = 0;
int rot_yaw = 0;
public:
FocusCCTV(CCTV* parent)
{
this->parent = parent;
}
virtual void update(double dt)
{
if(rot_pitch || rot_yaw)
{
parent->rotate(dt, rot_pitch, -rot_yaw);
}
if(zoom)
{
Data::Camera& active = parent->cameras[parent->camera_at];
active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom - zoom * dt * 0.5f), 1.f, 4.f);
}
}
virtual void on_keypress(int key, int sc, int action, int mods)
{
if(action == GLFW_PRESS)
{
switch(key)
{
case GLFW_KEY_KP_1:
parent->camera_at = (parent->camera_at + parent->cameras.size() - 1) % parent->cameras.size();
break;
case GLFW_KEY_KP_2:
rot_pitch -= 1;
break;
case GLFW_KEY_KP_3:
parent->camera_at = (parent->camera_at + 1) % parent->cameras.size();
break;
case GLFW_KEY_KP_4:
rot_yaw += 1;
break;
case GLFW_KEY_KP_5:
parent->powered = !parent->powered;
break;
case GLFW_KEY_KP_6:
rot_yaw -= 1;
break;
case GLFW_KEY_KP_7:
zoom += 1;
break;
case GLFW_KEY_KP_8:
rot_pitch += 1;
break;
case GLFW_KEY_KP_9:
zoom -= 1;
break;
}
}
else if(action == GLFW_RELEASE)
{
switch(key)
{
case GLFW_KEY_KP_2:
rot_pitch += 1;
break;
case GLFW_KEY_KP_4:
rot_yaw -= 1;
break;
case GLFW_KEY_KP_6:
rot_yaw += 1;
break;
case GLFW_KEY_KP_7:
zoom -= 1;
break;
case GLFW_KEY_KP_8:
rot_pitch -= 1;
break;
case GLFW_KEY_KP_9:
zoom += 1;
break;
}
}
}
};
CCTV::CCTV(Model& model)
: height(HEIGHT)
, width(HEIGHT * 16 / 9)
, cameras(model.cameras)
{
m_buttons[0] = model.load("click_cctv_numpad_1");
m_buttons[1] = model.load("click_cctv_numpad_2");
m_buttons[2] = model.load("click_cctv_numpad_3");
m_buttons[3] = model.load("click_cctv_numpad_4");
m_buttons[4] = model.load("click_cctv_numpad_5");
m_buttons[5] = model.load("click_cctv_numpad_6");
m_buttons[6] = model.load("click_cctv_numpad_7");
m_buttons[7] = model.load("click_cctv_numpad_8");
m_buttons[8] = model.load("click_cctv_numpad_9");
glGenFramebuffers(1, &fbo);
glGenTextures(1, &texture);
glGenRenderbuffers(1, &rbo_depth);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
handle = glGetTextureHandleARB(texture);
glMakeTextureHandleResidentARB(handle);
m_screen.vertices = {
{.texid=handle, .texpos={0, 1}, .pos={0, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
{.texid=handle, .texpos={0, 0}, .pos={0, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
{.texid=handle, .texpos={1, 1}, .pos={1, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
{.texid=handle, .texpos={1, 0}, .pos={1, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0},
};
m_screen.indices = {0, 1, 3, 0, 3, 2};
m_screen.transforms = {model.load_matrix("translation_monitor_1")};
m_screen.bake_transforms();
gm_screen.bind();
gm_screen.set(m_screen, GL_STATIC_DRAW);
}
CCTV::~CCTV()
{
if(fbo) glDeleteFramebuffers(1, &fbo);
if(texture) glDeleteTextures(1, &texture);
if(rbo_depth) glDeleteRenderbuffers(1, &rbo_depth);
}
CCTV::CCTV(CCTV&& o)
: width(o.width)
, height(o.height)
, cameras(std::move(o.cameras))
, gm_screen(std::move(o.gm_screen))
, m_screen(std::move(o.m_screen))
, m_buttons(std::move(o.m_buttons))
, powered(o.powered)
{
fbo = o.fbo;
texture = o.texture;
rbo_depth = o.rbo_depth;
handle = o.handle;
o.fbo = 0;
o.texture = 0;
o.rbo_depth = 0;
o.handle = 0;
}
void CCTV::rotate(double dt, float pitch, float yaw)
{
Data::Camera& active = cameras[camera_at];
float m = float(M_PI) * dt * 0.5f / active.zoom;
active.pitch = Util::Math::clamp(active.pitch + pitch * m, -M_PI / 4, M_PI / 4);
active.yaw = Util::Math::clamp(active.yaw + yaw * m, -M_PI / 4, M_PI / 4);
}
void CCTV::update(double dt)
{
Data::Camera& active = cameras[camera_at];
if(m_screen.check_focus())
Focus::set(std::make_unique<FocusCCTV>(this));
if(m_buttons[0].check_focus_hold())
active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom - dt * 0.5f), 1.f, 4.f);
if(m_buttons[1].check_focus_hold())
rotate(dt, 1, 0);
if(m_buttons[2].check_focus_hold())
active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom + dt * 0.5f), 1.f, 4.f);
if(m_buttons[3].check_focus_hold())
rotate(dt, 0, -1);
if(m_buttons[4].check_focus())
powered = !powered;
if(m_buttons[5].check_focus_hold())
rotate(dt, 0, 1);
if(m_buttons[6].check_focus())
camera_at = (camera_at + cameras.size() - 1) % cameras.size();
if(m_buttons[7].check_focus_hold())
rotate(dt, -1, 0);
if(m_buttons[8].check_focus())
camera_at = (camera_at + 1) % cameras.size();
}
void CCTV::render_view()
{
if(!powered)
return;
Data::Camera& active = cameras[camera_at];
glm::mat4 rot = glm::mat4(1);
glm::vec3 right = glm::normalize(glm::cross(active.look, active.up));
rot = glm::rotate(rot, -active.yaw, active.up);
rot = glm::rotate(rot, active.pitch, right);
glm::mat4 view = glm::lookAt(active.pos, active.pos + glm::mat3(rot) * active.look, active.up);
glm::mat4 proj = glm::perspective(active.fov / active.zoom, (float)width / height, 0.1f, 100.0f);
glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity());
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFrontFace(GL_CCW);
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &proj[0][0]);
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &view[0][0]);
glUniform3fv(Shader::MAIN["camera_pos"], 1, &active.pos[0]);
Window::render_scene();
Window::render_player();
}
void CCTV::render_screen()
{
if(!powered)
return;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBlendFunc(GL_SRC_COLOR, GL_ONE);
gm_screen.bind();
gm_screen.render();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

View File

@ -0,0 +1,47 @@
#pragma once
#include <vector>
#include <array>
#include "../data/meshgen.hpp"
#include "../data/camera.hpp"
#include "../data/glmesh.hpp"
namespace Sim::Graphics::Monitor
{
class CCTV : public Data::MeshGen
{
Data::GLMesh gm_screen;
Data::Mesh m_screen;
std::array<Data::Mesh, 9> m_buttons;
unsigned int fbo;
unsigned int texture;
unsigned int rbo_depth;
unsigned int handle;
const int width;
const int height;
public:
std::vector<Data::Camera> cameras;
int camera_at = 0;
bool powered = false;
CCTV(Data::Model& model);
CCTV(const CCTV&) = delete;
CCTV(CCTV&&);
~CCTV();
void update(double dt) override;
void rotate(double dt, float pitch, float yaw);
void render_view();
void render_screen();
};
};

View File

@ -3,10 +3,9 @@
#include <GLFW/glfw3.h>
#include "core.hpp"
#include "../locations.hpp"
#include "../input/focus.hpp"
#include "../mesh/arrays.hpp"
#include "../mesh/texture.hpp"
#include "../data/arrays.hpp"
#include "../data/texture.hpp"
#include "../../system.hpp"
#include "../../util/streams.hpp"
@ -18,6 +17,7 @@
using namespace Sim;
using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Util::Streams;
static void set_all(bool state)
@ -118,16 +118,16 @@ struct CoreJoystick : public Focus::FocusType
Core::Core(const Model& model)
{
mat = Locations::monitors[2];
m_buttons[0] = model.load("click_numpad_1");
m_buttons[1] = model.load("click_numpad_2");
m_buttons[2] = model.load("click_numpad_3");
m_buttons[3] = model.load("click_numpad_4");
m_buttons[4] = model.load("click_numpad_5");
m_buttons[5] = model.load("click_numpad_6");
m_buttons[6] = model.load("click_numpad_7");
m_buttons[7] = model.load("click_numpad_8");
m_buttons[8] = model.load("click_numpad_9");
mat = model.load_matrix("translation_monitor_3");
m_buttons[0] = model.load("click_reactor_numpad_1");
m_buttons[1] = model.load("click_reactor_numpad_2");
m_buttons[2] = model.load("click_reactor_numpad_3");
m_buttons[3] = model.load("click_reactor_numpad_4");
m_buttons[4] = model.load("click_reactor_numpad_5");
m_buttons[5] = model.load("click_reactor_numpad_6");
m_buttons[6] = model.load("click_reactor_numpad_7");
m_buttons[7] = model.load("click_reactor_numpad_8");
m_buttons[8] = model.load("click_reactor_numpad_9");
m_joystick = model.load("click_reactor_joystick");
m_monitor = model.load("translation_monitor_3");
m_scram = model.load("click_scram");
@ -135,14 +135,14 @@ Core::Core(const Model& model)
void Core::remesh_static(Mesh& rmesh)
{
Mesh mesh;
Data::Mesh mesh;
mesh.load_text("Reactor Core", 0.04);
rmesh.add(mesh, mat, true);
}
static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
static Data::Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour)
{
Mesh mesh;
Data::Mesh mesh;
mesh.indices = {0, 1, 3, 0, 3, 2};
mesh.vertices = {
@ -186,7 +186,7 @@ void Core::update(double dt)
void Core::remesh_slow(Mesh& rmesh)
{
Sim::System& sys = *System::active;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
double step = sys.reactor.cell_width / sys.vessel.diameter * 0.8;
double sx = 0.5 - (sys.reactor.width - 1) * step / 2.0;

View File

@ -1,27 +1,27 @@
#pragma once
#include "../mesh/model.hpp"
#include "../mesh/meshgen.hpp"
#include "../data/model.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Monitor
{
class Core : public MeshGen
class Core : public Data::MeshGen
{
glm::mat4 mat;
Mesh m_monitor;
Mesh m_buttons[9];
Mesh m_joystick;
Mesh m_scram;
Data::Mesh m_monitor;
Data::Mesh m_buttons[9];
Data::Mesh m_joystick;
Data::Mesh m_scram;
public:
Core(const Model& model);
virtual void update(double dt);
virtual void remesh_static(Mesh& rmesh);
virtual void remesh_slow(Mesh& rmesh);
Core(const Data::Model& model);
void update(double dt) override;
void remesh_static(Data::Mesh& rmesh) override;
void remesh_slow(Data::Mesh& rmesh) override;
};
};

View File

@ -3,7 +3,6 @@
#include <GLFW/glfw3.h>
#include "primary_loop.hpp"
#include "../locations.hpp"
#include "../../system.hpp"
#include "../../coolant/valve.hpp"
#include "../input/focus.hpp"
@ -14,6 +13,7 @@
using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Util::Streams;
struct ValveJoystick : public Focus::FocusType
@ -51,7 +51,7 @@ struct ValveJoystick : public Focus::FocusType
PrimaryLoop::PrimaryLoop(const Model& model)
{
mat = Locations::monitors[3];
mat = model.load_matrix("translation_monitor_4");
g_switch_pump = model.load("visual_pump_switch_1");
g_switch_bypass = model.load("visual_bypass_switch");
@ -67,7 +67,7 @@ PrimaryLoop::PrimaryLoop(const Model& model)
void PrimaryLoop::remesh_static(Mesh& rmesh)
{
std::stringstream ss;
Mesh mesh;
Data::Mesh mesh;
ss << "Turbine Bypass Valve\n\n";
ss << "Opened\nFlow\nSetpoint\n\n";
@ -108,7 +108,7 @@ void PrimaryLoop::update(double dt)
void PrimaryLoop::remesh_slow(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";

View File

@ -1,34 +1,34 @@
#pragma once
#include "../mesh/model.hpp"
#include "../mesh/meshgen.hpp"
#include "../data/model.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Monitor
{
class PrimaryLoop : public MeshGen
class PrimaryLoop : public Data::MeshGen
{
glm::mat4 mat;
Mesh m_joystick_turbine_bypass;
Mesh m_joystick_turbine_inlet;
Data::Mesh m_joystick_turbine_bypass;
Data::Mesh m_joystick_turbine_inlet;
Mesh g_switch_pump;
Mesh g_switch_bypass;
Mesh g_switch_inlet;
Data::Mesh g_switch_pump;
Data::Mesh g_switch_bypass;
Data::Mesh g_switch_inlet;
Mesh m_switch_pump;
Mesh m_switch_bypass;
Mesh m_switch_inlet;
Data::Mesh m_switch_pump;
Data::Mesh m_switch_bypass;
Data::Mesh m_switch_inlet;
public:
PrimaryLoop(const Model& model);
virtual void update(double dt);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
virtual void remesh_slow(Mesh& rmesh);
PrimaryLoop(const Data::Model& model);
void update(double dt) override;
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
void remesh_slow(Data::Mesh& rmesh) override;
};
};

View File

@ -3,7 +3,6 @@
#include <GLFW/glfw3.h>
#include "secondary_loop.hpp"
#include "../locations.hpp"
#include "../../system.hpp"
#include "../../coolant/valve.hpp"
#include "../input/focus.hpp"
@ -14,12 +13,12 @@
using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Util::Streams;
SecondaryLoop::SecondaryLoop(const Model& model)
{
mat = Locations::monitors[5];
mat = model.load_matrix("translation_monitor_6");
g_switch_2 = model.load("visual_pump_switch_2");
g_switch_3 = model.load("visual_pump_switch_3");
@ -43,7 +42,7 @@ void SecondaryLoop::update(double dt)
void SecondaryLoop::remesh_static(Mesh& rmesh)
{
std::stringstream ss;
Mesh mesh;
Data::Mesh mesh;
ss << "Cooling Tower\n\n";
ss << "Heat\nSteam\nPressure\nLevel\n\n";
@ -61,7 +60,7 @@ void SecondaryLoop::remesh_static(Mesh& rmesh)
void SecondaryLoop::remesh_slow(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";

View File

@ -1,31 +1,31 @@
#pragma once
#include "../mesh/model.hpp"
#include "../mesh/meshgen.hpp"
#include "../data/model.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Monitor
{
class SecondaryLoop : public MeshGen
class SecondaryLoop : public Data::MeshGen
{
glm::mat4 mat;
Mesh g_switch_2;
Mesh g_switch_3;
Mesh m_joystick_turbine_bypass;
Mesh m_joystick_turbine_inlet;
Mesh m_switch_2;
Mesh m_switch_3;
Data::Mesh g_switch_2;
Data::Mesh g_switch_3;
Data::Mesh m_joystick_turbine_bypass;
Data::Mesh m_joystick_turbine_inlet;
Data::Mesh m_switch_2;
Data::Mesh m_switch_3;
public:
SecondaryLoop(const Model& model);
virtual void update(double dt);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
virtual void remesh_slow(Mesh& rmesh);
SecondaryLoop(const Data::Model& model);
void update(double dt) override;
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
void remesh_slow(Data::Mesh& rmesh) override;
};
};

View File

@ -3,7 +3,6 @@
#include <GLFW/glfw3.h>
#include "turbine.hpp"
#include "../locations.hpp"
#include "../../system.hpp"
#include "../../coolant/valve.hpp"
#include "../input/focus.hpp"
@ -15,11 +14,12 @@
using namespace Sim::Graphics;
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Util::Streams;
Turbine::Turbine(const Model& model)
{
mat = Locations::monitors[4];
mat = model.load_matrix("translation_monitor_5");
g_dial_phase = model.load("visual_dial_phase");
g_dial_voltage = model.load("visual_dial_voltage");
@ -69,7 +69,7 @@ void Turbine::get_static_transforms(std::vector<glm::mat4>& transforms)
void Turbine::remesh_static(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
ss << "Turbine\n\n";
ss << "Heat\nPressure\nSpeed\n\n";
@ -87,7 +87,7 @@ void Turbine::remesh_static(Mesh& rmesh)
void Turbine::remesh_slow(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
System& sys = *System::active;
ss << "\n\n";

View File

@ -1,31 +1,31 @@
#pragma once
#include "../mesh/model.hpp"
#include "../mesh/glmesh.hpp"
#include "../mesh/meshgen.hpp"
#include "../data/model.hpp"
#include "../data/glmesh.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Monitor
{
class Turbine : public MeshGen
class Turbine : public Data::MeshGen
{
glm::mat4 mat;
Mesh g_dial_phase;
Mesh g_dial_voltage;
Mesh g_dial_power;
Mesh g_dial_frequency;
Mesh g_switch_breaker;
Mesh m_switch_breaker;
Data::Mesh g_dial_phase;
Data::Mesh g_dial_voltage;
Data::Mesh g_dial_power;
Data::Mesh g_dial_frequency;
Data::Mesh g_switch_breaker;
Data::Mesh m_switch_breaker;
public:
Turbine(const Model& model);
virtual void update(double dt);
virtual void get_static_transforms(std::vector<glm::mat4>& transforms);
virtual void remesh_static(Mesh& rmesh);
virtual void remesh_slow(Mesh& rmesh);
Turbine(const Data::Model& model);
void update(double dt) override;
void get_static_transforms(std::vector<glm::mat4>& transforms) override;
void remesh_static(Data::Mesh& rmesh) override;
void remesh_slow(Data::Mesh& rmesh) override;
};
};

View File

@ -5,7 +5,6 @@
#include "vessel.hpp"
#include "../../reactor/rod.hpp"
#include "../../reactor/control/boron_rod.hpp"
#include "../locations.hpp"
#include "../../system.hpp"
#include "../../util/streams.hpp"
@ -13,17 +12,18 @@
#include <sstream>
using namespace Sim::Graphics::Monitor;
using namespace Sim::Graphics::Data;
using namespace Sim::Util::Streams;
Vessel::Vessel(const Model& model)
{
mat = Locations::monitors[1];
mat = model.load_matrix("translation_monitor_2");
}
void Vessel::remesh_static(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
ss << "Reactor Vessel\n\n";
ss << "Heat\n";
@ -44,7 +44,7 @@ void Vessel::remesh_static(Mesh& rmesh)
void Vessel::remesh_slow(Mesh& rmesh)
{
std::stringstream ss;
Sim::Graphics::Mesh mesh;
Sim::Graphics::Data::Mesh mesh;
Sim::System& sys = *System::active;
double temp_min, temp_max;

View File

@ -1,21 +1,21 @@
#pragma once
#include "../mesh/model.hpp"
#include "../mesh/meshgen.hpp"
#include "../data/model.hpp"
#include "../data/meshgen.hpp"
namespace Sim::Graphics::Monitor
{
class Vessel : public MeshGen
class Vessel : public Data::MeshGen
{
glm::mat4 mat;
public:
Vessel(const Model& model);
virtual void remesh_static(Mesh& rmesh);
virtual void remesh_slow(Mesh& rmesh);
Vessel(const Data::Model& model);
void remesh_static(Data::Mesh& rmesh) override;
void remesh_slow(Data::Mesh& rmesh) override;
};
};

View File

@ -7,6 +7,7 @@
using namespace Sim::Graphics;
using namespace Sim::Graphics::Resize;
using namespace Sim::Graphics::Window;
static bool is_fullscreen = false;

View File

@ -5,6 +5,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
#include <format>
#include "shader.hpp"
#include "window.hpp"
@ -12,26 +13,20 @@
using namespace Sim::Graphics;
Shader Shader::MAIN;
Shader Shader::BLUR;
Shader Shader::LIGHT;
Shader* Shader::ACTIVE;
static int load_shader(const char* src, int type)
{
int id = glCreateShader(type);
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
return id;
}
static std::string read_shader(const char* path)
{
std::stringstream ss;
std::ifstream file(path, std::ios::binary);
char buff[1024];
if(!file.is_open())
{
throw std::runtime_error(std::format("Shader Read Error: {0}", path));
}
while(!file.eof())
{
file.read(buff, 1024);
@ -47,6 +42,37 @@ static std::string read_shader(const char* base, const char* file)
return read_shader(path.c_str());
}
Shader::Source::Source(const char* path, GLenum type)
{
int success;
std::string src = read_shader(path);
const char* c_src = src.c_str();
id = glCreateShader(type);
glShaderSource(id, 1, &c_src, nullptr);
glCompileShader(id);
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if(!success)
{
char infoLog[512];
glGetShaderInfoLog(id, 512, NULL, infoLog);
std::string entry = std::format("Shader Compile Error ({0}): {1}", path, infoLog);
throw std::runtime_error(entry);
}
}
Shader::Source::Source(Source&& o)
{
id = o.id;
o.id = 0;
}
Shader::Source::~Source()
{
if(id) glDeleteShader(id);
}
Shader::Shader()
{
@ -66,30 +92,15 @@ Shader::~Shader()
}
}
void Shader::load(const char* path, const char* file_vsh, const char* file_fsh)
void Shader::load(const Source* sources, int count)
{
load(path, file_vsh, nullptr, file_fsh);
}
void Shader::load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh)
{
std::string shader_vsh = file_vsh ? read_shader(path, file_vsh) : "";
std::string shader_gsh = file_gsh ? read_shader(path, file_gsh) : "";
std::string shader_fsh = file_fsh ? read_shader(path, file_fsh) : "";
int success;
int vsh_id = file_vsh ? load_shader(shader_vsh.c_str(), GL_VERTEX_SHADER) : 0;
int gsh_id = file_gsh ? load_shader(shader_gsh.c_str(), GL_GEOMETRY_SHADER) : 0;
int fsh_id = file_fsh ? load_shader(shader_fsh.c_str(), GL_FRAGMENT_SHADER) : 0;
prog_id = glCreateProgram();
if(file_vsh)
glAttachShader(prog_id, vsh_id);
if(file_gsh)
glAttachShader(prog_id, gsh_id);
if(file_fsh)
glAttachShader(prog_id, fsh_id);
for(int i = 0; i < count; i++)
{
glAttachShader(prog_id, sources[i].id);
}
glLinkProgram(prog_id);
glGetProgramiv(prog_id, GL_LINK_STATUS, &success);
@ -98,21 +109,9 @@ void Shader::load(const char* path, const char* file_vsh, const char* file_gsh,
{
char infoLog[512];
glGetProgramInfoLog(prog_id, 512, NULL, infoLog);
std::cout << "Shader Link Error (" << path << "," << file_vsh << "," << file_fsh << "): " << infoLog << std::endl;
Window::close();
return;
std::string entry = std::format("Shader Link Error: {0}", infoLog);
throw std::runtime_error(entry);
}
glUseProgram(prog_id);
if(file_vsh)
glDeleteShader(vsh_id);
if(file_gsh)
glDeleteShader(gsh_id);
if(file_fsh)
glDeleteShader(fsh_id);
ACTIVE = this;
}
void Shader::use()

View File

@ -1,11 +1,14 @@
#pragma once
#include <GL/glew.h>
#include <unordered_map>
namespace Sim::Graphics
{
class Shader
{
unsigned int prog_id = 0;
@ -14,9 +17,18 @@ class Shader
std::unordered_map<const char*, unsigned int> uniform_block_indices;
public:
struct Source
{
unsigned int id;
Source(const char* path, GLenum type);
Source(const Source& o) = delete;
Source(Source&& o);
~Source();
};
static Shader MAIN;
static Shader BLUR;
static Shader LIGHT;
static Shader* ACTIVE;
@ -26,8 +38,7 @@ public:
Shader(Shader&& o);
~Shader();
void load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh);
void load(const char* path, const char* file_vsh, const char* file_fsh);
void load(const Source* sources, int count);
void block_binding(const char* name, unsigned int index);
void use();

View File

@ -6,11 +6,11 @@
#include <glm/ext/matrix_transform.hpp>
#include "mesh/mesh.hpp"
#include "mesh/glmesh.hpp"
#include "mesh/arrays.hpp"
#include "mesh/font.hpp"
#include "mesh/texture.hpp"
#include "data/mesh.hpp"
#include "data/glmesh.hpp"
#include "data/arrays.hpp"
#include "data/font.hpp"
#include "data/texture.hpp"
#include "resize.hpp"
#include "shader.hpp"
@ -18,18 +18,17 @@
using namespace Sim::Graphics;
static GLMesh gm_ui;
static GLMesh gm_dynamic_slow[2];
static Data::GLMesh gm_ui;
static Data::GLMesh gm_dynamic_slow[2];
static Widget::Clock w_clock;
static int gm_dynamic_slow_at = 0;
void UI::init()
{
Mesh m;
Data::Mesh m;
unsigned int handle = Texture::handle_white;
unsigned int handle = Data::Texture::handle_white;
m.indices = {0, 1, 3, 0, 3, 2};
m.vertices = {
{.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}},
@ -51,10 +50,12 @@ void UI::update(double dt)
void UI::update_slow()
{
Mesh mesh;
Data::Mesh mesh;
w_clock.remesh_slow(mesh);
mesh.bake_transforms();
gm_dynamic_slow[gm_dynamic_slow_at].bind();
gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_DYNAMIC_DRAW);
gm_dynamic_slow_at = (gm_dynamic_slow_at + 1) % 2;

View File

@ -10,14 +10,15 @@
#include <sstream>
#include <cmath>
#include "../mesh/arrays.hpp"
#include "../mesh/font.hpp"
#include "../mesh/arrays.hpp"
#include "../data/arrays.hpp"
#include "../data/font.hpp"
#include "../data/arrays.hpp"
#include "../resize.hpp"
#include "../../system.hpp"
#include "../../util/streams.hpp"
using namespace Sim::Graphics::Widget;
using namespace Sim::Graphics::Data;
void Clock::update(double dt)
{

View File

@ -1,7 +1,7 @@
#pragma once
#include "../mesh/glmesh.hpp"
#include "../data/glmesh.hpp"
namespace Sim::Graphics::Widget
{
@ -11,7 +11,7 @@ struct Clock
double dt;
void update(double dt);
void remesh_slow(Mesh& rmesh);
void remesh_slow(Data::Mesh& rmesh);
};
};

View File

@ -10,8 +10,8 @@
#include <vector>
#include <memory>
#include "mesh/mesh.hpp"
#include "mesh/arrays.hpp"
#include "data/mesh.hpp"
#include "data/arrays.hpp"
#include "input/keyboard.hpp"
#include "input/mouse.hpp"
#include "input/focus.hpp"
@ -19,17 +19,17 @@
#include "resize.hpp"
#include "window.hpp"
#include "shader.hpp"
#include "mesh/font.hpp"
#include "locations.hpp"
#include "data/font.hpp"
#include "monitor/vessel.hpp"
#include "monitor/core.hpp"
#include "monitor/primary_loop.hpp"
#include "monitor/secondary_loop.hpp"
#include "monitor/turbine.hpp"
#include "mesh/texture.hpp"
#include "mesh/model.hpp"
#include "mesh/gllight.hpp"
#include "mesh/meshgen.hpp"
#include "monitor/cctv.hpp"
#include "data/texture.hpp"
#include "data/model.hpp"
#include "data/gllight.hpp"
#include "data/meshgen.hpp"
#include "equipment/reactor.hpp"
#include "equipment/generator.hpp"
#include "equipment/pool.hpp"
@ -38,6 +38,7 @@
#include "ui.hpp"
using namespace Sim::Graphics;
using namespace Sim::Graphics::Data;
constexpr int SSBO_TRANSFORMS_LEN = 2;
@ -55,11 +56,14 @@ static Mesh g_scene;
static std::vector<glm::mat4> g_scene_transforms;
static GLMesh gm_scene;
static GLMesh gm_player;
static GLMesh gm_dynamic_slow[2];
static std::vector<GLLight> lights;
static std::vector<std::unique_ptr<MeshGen>> monitors;
static std::vector<std::unique_ptr<MeshGen>> equipment;
static std::vector<MeshGen*> monitors;
static std::vector<MeshGen*> equipment;
static Monitor::CCTV* monitor_cctv;
glm::mat4 Window::projection_matrix;
@ -90,21 +94,15 @@ void remesh_static()
equipment->remesh_static(mesh);
}
gm_scene.bind(false);
gm_scene.set(mesh, GL_STATIC_DRAW, false);
gm_scene.bind();
gm_scene.set(mesh, GL_STATIC_DRAW);
g_scene_transforms = std::move(mesh.transforms);
std::cout << "Total triangles: " << mesh.indices.size() / 3 << "\n";
std::cout << "Total triangle count: " << mesh.indices.size() / 3 << "\n";
}
void render_shadow_map()
{
Shader::LIGHT.use();
for(auto& light : lights)
{
light.render();
}
}
void Window::create()
@ -165,21 +163,36 @@ void Window::create()
Font::init();
UI::init();
Shader::MAIN.load("../assets/shader", "main.vsh", "main.fsh");
// load all the shaders
Shader::Source sources_main[] = {
{"../assets/shader/main.vsh", GL_VERTEX_SHADER},
{"../assets/shader/main.fsh", GL_FRAGMENT_SHADER},
};
Shader::Source sources_light[] = {
{"../assets/shader/light.vsh", GL_VERTEX_SHADER},
{"../assets/shader/light.gsh", GL_GEOMETRY_SHADER},
{"../assets/shader/light.fsh", GL_FRAGMENT_SHADER},
};
Shader::MAIN.load(sources_main, 2);
Shader::LIGHT.load(sources_light, 3);
Shader::MAIN.use();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Sim::System& sys = *System::active;
Mesh m_transparent;
Model model("../assets", "scene.glb");
Mesh m_player = model.load("visual_player");
gm_player.bind();
gm_player.bind_ssbo();
gm_player.set(m_player, GL_STATIC_DRAW);
g_scene.add(model.load("cr"));
g_scene.add(model.load("cb"));
g_scene.add(model.load("hw"));
g_scene.bake_transforms();
std::cout << "Static scene triangles: " << g_scene.indices.size() / 3 << "\n";
Camera::init(model);
// send all the light data
@ -190,21 +203,23 @@ void Window::create()
glUniform1i(Shader::MAIN["lights_count"], model.lights.size());
monitors.push_back(std::make_unique<Monitor::Core>(model));
monitors.push_back(std::make_unique<Monitor::Vessel>(model));
monitors.push_back(std::make_unique<Monitor::PrimaryLoop>(model));
monitors.push_back(std::make_unique<Monitor::SecondaryLoop>(model));
monitors.push_back(std::make_unique<Monitor::Turbine>(model));
equipment.push_back(std::make_unique<Equipment::Reactor>(model));
equipment.push_back(std::make_unique<Equipment::Generator>(model));
equipment.push_back(std::make_unique<Equipment::Pool>(model));
monitors.push_back(new Monitor::Core(model));
monitors.push_back(new Monitor::Vessel(model));
monitors.push_back(new Monitor::PrimaryLoop(model));
monitors.push_back(new Monitor::SecondaryLoop(model));
monitors.push_back(new Monitor::Turbine(model));
monitors.push_back(monitor_cctv = new Monitor::CCTV(model));
equipment.push_back(new Equipment::Reactor(model));
equipment.push_back(new Equipment::Generator(model));
equipment.push_back(new Equipment::Pool(model));
remesh_static();
glfwShowWindow(win);
// setup lighting and prerender shadows
Shader::LIGHT.load("../assets/shader", "light.vsh", "light.gsh", "light.fsh");
Shader::LIGHT.use();
glUniform1f(Shader::LIGHT["far_plane"], 100.0f);
GLLight::init();
@ -322,9 +337,16 @@ void Window::update(double dt)
}
}
void Window::render_player()
{
gm_player.bind();
gm_player.bind_ssbo();
gm_player.render();
}
void Window::render_scene()
{
gm_scene.bind(false);
gm_scene.bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]);
gm_scene.render();
@ -336,32 +358,49 @@ void Window::render_scene()
void Window::render()
{
render_shadow_map();
Shader::LIGHT.use();
for(auto& light : lights)
{
light.render();
}
glm::vec<2, int> size = Resize::get_size();
glm::vec3 camera_pos = Camera::get_pos();
glm::mat4 mat_camera = Camera::get_matrix();
Shader::MAIN.use();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, size.x, size.y);
glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity());
glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 100.f);
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
glm::mat4 mat_player = glm::mat4(1);
mat_player = glm::translate(mat_player, glm::vec3(Camera::get_pos_base()));
mat_player = glm::rotate(mat_player, (float)glm::radians(90 - Camera::get_yaw()), glm::vec3(0, 0, 1));
glBindBuffer(GL_SHADER_STORAGE_BUFFER, gm_player.ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(glm::mat4), &mat_player, GL_STREAM_DRAW);
monitor_cctv->render_view();
glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]);
glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]);
projection_matrix = mat_projection;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glViewport(0, 0, size.x, size.y);
glFrontFace(GL_CCW);
glClearColor(0, 0, 0, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
render_scene();
monitor_cctv->render_screen();
brightness = glm::vec3(1);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]);
glClear(GL_DEPTH_BUFFER_BIT);
UI::render();
Focus::render_ui();

View File

@ -17,6 +17,7 @@ void reload();
void update(double dt);
void render();
void render_scene();
void render_player();
void destroy();
void close();

View File

@ -10,7 +10,6 @@
#include "coolant/valve.hpp"
#include "coolant/pump.hpp"
#include "graphics/mesh/mesh.hpp"
#include "graphics/input/focus.hpp"
#include "graphics/window.hpp"

View File

@ -19,13 +19,24 @@ constexpr double j_to_ms2(double j, double mass)
return m*std::sqrt(m * j / (mass * 0.001));
}
constexpr float map(float v, float imin, float imax, float omin, float omax)
template <typename A>
constexpr A map(A v, auto imin, auto imax, auto omin, auto omax)
{
return (v - imin) * (omax - omin) / (imax - imin) + omin;
}
template<typename A, typename B>
constexpr A mod(A a, B b)
template <typename A>
constexpr A clamp(A v, auto min, auto max)
{
if(v < min)
return min;
if(v > max)
return max;
return v;
}
template <typename A>
constexpr A mod(A a, auto b)
{
A v = std::fmod(a, b);